'migrating to yarn 3 + workspaces + nohoist

I'm migrating from yarn 1.xx to yarn 3 and I'm currently having a workspaces definition with nohoist configuration in my package.json:

  "workspaces": {
    "packages": [
      "packages/*"
    ],
    "nohoist": [
      "**/react-router-dom",
      "**/react-router"
    ]
  },

the new version of yarn does not support the nohoist feature the way it used to in previous version.
Yarn 3 has this nmHoistingLimits config which has only 3 options (workspaces , dependencies, none) - the only option to no-hoist a dependency inside a workspace (i.e. a package module in the monorepo) is to use the workspaces option but then each workspace (i.e. a package module) has its own node_modules folder, while their dependencies are hoisted to the root’s node_modules. I ended up with a lot of common dependencies not hoisted up to the root. does anyone found a workaround for it? How can I get the following functionality, where I can no-hoist only certain dependencies?



Solution 1:[1]

I’m wondering about the same thing. I think nohoist still works, though. It’s just deprecated.

Can you have nested .yarnrc.yml files to override the new setting per workspace?

Is there a way to define it per workspace somehow within package.json?

It does seem that the new options are much less granular than before.

In my case in only want it to apply to one package out of about 10.

UPDATE: I think I have a solution. You can indeed add a .yarnrc.yml file in the folder of a particular workspace that you do not want to hoist its dependencies.

It only needs to contain this single line:

nmHoistingLimits: workspaces

I confirmed this is respected by running yarn config -v in the root of my repo then again within the workspace. All other settings were inherited from the root .yarnrc.yml file, but the nmHoistingLimits setting changed from none to workspaces.

You still don't have the per-package granularity of before, which I think was intentional. However, allowing most workspaces to hoist their dependencies should hopefully provide some benefit.

UPDATE 2 - Something that works.

I've realized that installConfig is a section of package.json. Each workspace can define this section to override the default behaviour:

<repo-root>/packages/my-package/package.json:

{
  ...
  "installConfig": {
    "hoistingLimits": "workspaces"
  }
  ...
}

I can confirm that after doing this and running yarn at the repo root, my offending child package kept its dependencies in its own node_modules folder.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1