19

I'm relatively new to using Yarn Workspaces and having a Monorepo set up, so forgive me if this has been answered. I don't believe I've found a clear answer on whether or not this is possible for a Monorepo set up using Yarn Workspaces.

I'd like to know if it's possible to use two different versions of a dependency (in my case TypeScript) in different packages and how to do that.

My goal is to lock a version of TypeScript (3.4.5) in Package A and use the root package.json's version (3.5.0) of TypeScript for all other Packages in this monorepo.

This is the folder structure. Ideally, PackageA would use 3.4.5 and PackageB/PackageC would use whatever version is defined in the root package.json

|-- packages
    |-- packageA
    |-- packageB 
    |-- packageC
|-- package.json

This is what I've tried so far:

I have tried adding nohoist in my workspace options in the webpack config, but I don't believe Package A is using TypeScript 3.4.5 as I am not getting the expected result. When I change the root package.json TypeScript version requirement to 3.4.5, thats when I get the correct result, it would be the best case scenario if I could keep using the latest TS for all other packages but keep the lower version for Package A.

I've also tried adding a package.json in the PackageA folder where it defines "typescript": "3.4.5" as a devDependency. Yarn installs the right version in the PackageA folder, but it doesn't seem to use it.

I'm also pretty sure Yarn resolutions is not the right tool for this situation either as my packages aren't defined as dependencies in my package.json.

snippet of package.json
  "devDependenices: {
    ...,
    "webpack": "^4.34.0",
    "typescript": "3.5.0-rc",
    "yarn": "^1.15.2"
  },
  "workspaces": {
    "packages": [
      "packages/*"
    ],
    "nohoist": [
      "packageA/typescript"
    ]
  }

If anyone's curious, PackageA needs to use TypeScript 3.4.5 because I need react-docgen-typescript to parse Prop values that exist on the Prop and not it's parent (i.e HTML attributes on a button would display as a prop). Here's a link to that issue.

Please let me know if any more information is needed for my project configuration! Appreciate the insight and advice :)

5
  • 2
    Yarn installs the right version in the PackageA folder, but it doesn't seem to use it - so, as far as yarn is concerned, it did the thing that it was asked to do. Now the question is "why it doesn't seem to use it", that is, why PackageA is not using typescript installed in its own local node_modules, but is using some other version instead. This looks to be a question more about PackageA or whatever tool is using typescript on PackageA sources, and not so much about yarn workspaces.
    – artem
    Commented Jul 9, 2019 at 1:42
  • @artem I appreciate the comment! Do you know if there is a way to confirm which version of a dependency is run when running scripts at the root of the project defined in the root package.json? Commented Jul 9, 2019 at 3:16
  • For typescript, using -v command line option will make it print its version, but it won't do anything else besides that. For other scripts - I don't know. In general, if you run script in the root directory, it should pick its dependencies from the root node_modules only. If you need to run a script in the context of a particular package ("workspace" in yarn terminology) there is yarn workspace yarn command for that.
    – artem
    Commented Jul 9, 2019 at 6:18
  • 4
    I love how all the tutorials out there are like... just use yarn workspaces! But the whole point of setting of a monorepo is that you kind of need to support building of different subprojects with different versions of dependencies, but none of these tutorials tell you how to do that! Ha
    – Otto
    Commented Nov 25, 2020 at 15:04
  • @ShermanHui Have you figured out the solution? Commented Nov 30, 2020 at 4:42

1 Answer 1

11

According to documentation, you have to add ** beside the package name to avoid hoisting the package. Documentation link here.
To only avoid hoisting for typescript:

"workspaces": {
  "packages": [
    "packages/*"
  ],
  "nohoist": [
    "packageA/typescript/**"
  ]
}

To avoid hoisting for typescript and it's dependencies as well:

"workspaces": {
  "packages": [
    "packages/*"
  ],
  "nohoist": [
    "packageA/typescript/**/**"
  ]
}
2
  • 3
    nohoist doesn't exist any more in Yarn 4. What's the modern solution to this problem?
    – fr0
    Commented Jan 30 at 17:55
  • @fr0: There doesn't seem to be one. This comment from one of the yarn maintainers says that if you need to suppress hoisting for individual modules, you're doing it wrong: github.com/yarnpkg/berry/issues/4423#issuecomment-1115082597
    – broofa
    Commented Apr 16 at 14:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.