Yarn: Yarn Workspaces hoisting in nested packages with different versions of a dependency results in importing wrong dependency version

Created on 19 Apr 2020  路  4Comments  路  Source: yarnpkg/yarn

Bug description

In a Yarn Workspaces project, if I have nested packages like so:

root/package.json <-- workspace definition
root/parentPackage/package.json <-- dependent on lodash@v1
root/parentPackage/childPackage/package.json <--dependent on lodash@v4
root/differentPackage/package.json <-- dependent on lodash@v4

Running yarn will result in lodash@v4 being hoisted to the root node_modules, and lodash@v1 sitting in root/parentPackage/node_modules. This means that childPackage will import lodash@v1 when it expects lodash@v4 and will encounter runtime errors.

You can fix this with nohoist, but you'd have to manually nohoist each package that's problematic which takes a long while. Also, you need to delete your lockfiles between running yarn since changing the nohoist config and running yarn again does not change module locations.

Command

yarn

What is the current behavior?
Yarn hoists the package version with most usages to root version even if one of the modules in the workspace will resolve its import to a different version due to having a parent package that's dependent on the different version.

What is the expected behavior?
When hoisting packages, Yarn should check if it means that one of the workspace modules will resolve that package to a bad version due to its parent. If so, Yarn should keep a copy of this package in the nested module's node_modules (and maybe it also shouldn't count it as a usage when calculating which packages to hoist by most used version, but this is an optimization).

Steps to Reproduce
https://github.com/PeledYuval/yarn-workspace-hoist-bug
Clone that repo, run yarn in the root level.

In that repo, you have:

root/package.json <- contains workspaces definition
root/service/package.json <-- dependent on lodash@^4.0.0
root/client/package.json <-- dependent on lodash@^1.0.0
root/client/app/package.json <-- dependent on lodash@^4.0.0

Running yarn results in:

root/node_modules/lodash <-- v4.0.0
root/client/node_modules/lodash <-- v1.0.0

Clone the repo, then run yarn && node client/app in the project root. You will see that the run fails because client/app resolves require('lodash') to v1 when it expects v4.

Environment

  • Node Version: 12.6.1
  • Yarn v1 Version: 1.19.0
  • OS and version: macOS 10.14.6

Most helpful comment

+1

For now: using nohoist works, but would like more intelligent hoisting

All 4 comments

I'd love some input on this from Yarn maintainers / experts - am I missing something?

This issue is still relevant.

+1

For now: using nohoist works, but would like more intelligent hoisting

This issue is still relevant.

Was this page helpful?
0 / 5 - 0 ratings