pnpm: PNPM is incorrectly providing the same dependency version to multiple packages relying on different versions
pnpm version: 7.8.0
Code to reproduce the issue:
Attached is a very basic project with two packages, each relying on only a single devDependency (jest) - but each package has a different version of that same dependency. I have added a script jest-version
which just logs the jest version for ease of use.
Package-1 - package.json:
"name": "package-1",
"version": "1.0.0",
"description": "Package 1",
"license": "UNLICENSED",
"scripts": {
"jest-version": "jest --version"
},
"devDependencies": {
"jest": "^27.5.1"
}
}
Package-2 - package.json:
"name": "package-2",
"version": "1.0.0",
"description": "Package 2",
"license": "UNLICENSED",
"scripts": {
"jest-version": "jest --version"
},
"devDependencies": {
"jest": "^24.8.0"
}
}
Expected behaviour:
I would expect when running pnpm jest-version
in package-1 I would get an output of 27.5.1
, and when running pnpm jest-version
in package-2 I would get an output of 24.8.0
.
Actual behaviour:
I get an output of 24.8.0
for the command in both packages.
Additional information:
node -v
prints: v16.16.0- Windows, macOS, or Linux?: Windows and macOS.
For what its worth, this does behave expected on npm (8.11.0).
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 6
- Comments: 33 (13 by maintainers)
Commits related to this issue
- fix: multiple Jest versions in a single workspace should work close #5176 — committed to pnpm/pnpm by zkochan a year ago
- fix: don't extend NODE_PATH in command shims close #5285 close #5176 — committed to pnpm/pnpm by zkochan 2 years ago
- fix: multiple Jest versions in a single workspace should work close #5176 — committed to pnpm/pnpm by zkochan a year ago
- fix: multiple Jest versions in a single workspace should work (#6138) close #5176 close #6213 — committed to pnpm/pnpm by zkochan a year ago
- fix: don't extend NODE_PATH in command shims (#5290) close #5285 close #5176 — committed to zackerydev/pnpm by zkochan a year ago
Dang,
@types/react
is breaking again. The weird error message may be a clue to what’s going wrong. To recap, the project has two packages, one of which uses@types/react@18
and one uses@types/react@17
. With any combination ofhoist=false
,public-hoist-pattern=[]
,public-hoist-pattern[]=
typesetc.,
tsc` fails with a weird import:(this is in the package which has
@types/react@^17
)This might be a tsc issue, but I would still assume that it should work with pnpm out-of-the-box.
If anyone else is hitting this we have a sort of workaround that doesn’t require changing hoist patterns
This resolves to the right version of jest
This seems to also happen with tsc and multiple @types library versions, with tsc always using the alphabetically first (older) @types library.
I’m unfortunately experiencing a similar problematic behaviour. I don’t think this is an issue with just Jest and hoisting in particular given that this used to work properly before I upgraded to pnpm 7 (in version 6.32.8).
Everything worked as expected before updating, the correct version of Jest was instanced in the expected workspace, but not anymore.
One thing that I noticed is that (in version 7) this only happens after I run
pnpm install
. If I reinstall Jest manually by uninstalling and reinstalling it (withpnpm i -D jest@version
), the next time I runpnpm jest --version
it will print the correct version. But as soon as I runpnpm install
again, the wrong version will be printed again.I cannot reproduce the
next dev
issue anymore. And I cannot think of a reason why anything would break if I remove NODE_PATH patching. So, I will remove itI highly recommend turning off
public-hoist-pattern[]
completely. We had it on for years with a large monorepo and it caused us unbelievable issues because we had phantom@types
dependencies that would result in very confusing and non-deterministic typechecking results.🚢 7.29.3
Right, I was not expecting that the removal of NODE_PATH would break anything as the
node_modules/.pnpm/node_modules
directory should be looked into by default, when resolving require statements in subdirs ofnode_modules/.pnpm/
. Maybe some pluggable tools use the value of NODE_PATH explicitly.@zkochan Is there a reason
extend-node-path
was removed? Before upgrading to v7 I used this to workaround the issue. Now the suggested fix is to sethoist=false
. We have always used the default hoist settings and I always thought pnpm was strict by default when it came to dependencies. What are the downsides tohoist=false
?@boiboif @ConcernedHobbit This issue cost us several days. But in our case it was not an issue with pnpm but with tsc and ts-jest.
More specifically, in certain scenarios tsc traverses up your directory tree. Effectively ignoring whatever you declared in “typeRoots”.
To fix this we had to add “react” to “paths” in tsconfig.json. See:
in v6 in
packages/A
I runpnpm jest --version
and see the version frompackages/A/package.json
- 28, with pnpm 7 I do the same and get another version - 26.6.3 (which is probably frompackages/B
package.json)I checked
packages/A/node_modules/.bin/jest
and found out thereexec node "$basedir/../../../../nodemodules/.pnpm/jest@28.1.0@types+node@14.17.21/node_modules/jest/bin/jest.js" "$@"
which is correct 🙂 and if I run this command manually in my terminal from thepackages/A/node_modules/.bin
folder, it works as expected - prints version 28the main diff I found is in this line
export NODE_PATH="/Users/uhavenchyk/p/my-project/node_modules/.pnpm/node_modules"
from thepackages/A/node_modules/.bin/jest
in v7, in v6 it’s a way longerLooks like it is some issue with Jest, when hoisting is used.
Add this
.npmrc
to the root of your workspace:Run
pnpm install
and it works fine.