Open dmnd opened 2 years ago
For now I've worked around this with a resolution, so that random transitive dependency doesn't install a different tsc.
I vaguely remember working on some of that linker behavior years ago: https://github.com/yarnpkg/yarn/blob/master/src/package-linker.js#L578-L593
IIRC, I had set it up so that direct dependencies would overwrite transitive ones (the simplest thing to fix #4937 ), but the behavior for bin links of transitive deps is a bit "undefined". I think it would just be whichever transitive dep is linked last.
In general, I don't think you should be depending on bin links for transitive deps. If you plan to exec their bins, then making a direct dependency is the safest thing to do.
Good point @rally25rs. We're using workspaces, so here the problem was that workspace direct dependencies get overwritten by transitive dependencies. But since I wrote up this issue, we ended up adding the dependency at root for a different reason (VS Code).
I've experienced this as well, a dependency that is directly declared at the root being superseded in .bin by a transitive dependency.
After running yarn install
, the version that ends up in .bin is what I expect it to be. But after yarn add
ing any dependency in any workspace, the version in .bin is the transitive dependency.
# 1
❯ yarn install
yarn install v1.22.19
[1/4] 🔍 Resolving packages...
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...
[4/4] 🔨 Building fresh packages...
✨ Done in 1.55s.
# 2
❯ yarn why prettier
yarn why v1.22.19
[1/4] 🤔 Why do we have the module "prettier"...?
[2/4] 🚚 Initialising dependency graph...
[3/4] 🔍 Finding dependency...
[4/4] 🚡 Calculating file sizes...
=> Found "prettier@2.8.4"
info Has been hoisted to "prettier"
info Reasons this module exists
- "workspace-aggregator-a42f4464-5bf4-43b0-83e3-95dcf9900c47" depends on it
- Specified in "devDependencies"
- Hoisted from "_project_#prettier"
info Disk size without dependencies: "11.21MB"
info Disk size with unique dependencies: "11.21MB"
info Disk size with transitive dependencies: "11.21MB"
info Number of shared dependencies: 0
=> Found "@storybook/mdx1-csf#prettier@2.3.0"
info This module exists because "_project_#@ywsvb#package-with-transitive-prettier-dep#@storybook#addon-essentials#@storybook#addon-docs#@storybook#mdx1-csf" depends on it.
info Disk size without dependencies: "19.01MB"
info Disk size with unique dependencies: "19.01MB"
info Disk size with transitive dependencies: "19.01MB"
info Number of shared dependencies: 0
=> Found "@storybook/source-loader#prettier@2.3.0"
info This module exists because "_project_#@ywsvb#package-with-transitive-prettier-dep#@storybook#addon-essentials#@storybook#addon-docs#@storybook#source-loader" depends on it.
info Disk size without dependencies: "19.01MB"
info Disk size with unique dependencies: "19.01MB"
info Disk size with transitive dependencies: "19.01MB"
info Number of shared dependencies: 0
✨ Done in 0.26s.
# 3
❯ yarn prettier -v
yarn run v1.22.19
$ /Users/jonscheiding/Code/Personal/yarn-workspace-bin-version-issue/node_modules/.bin/prettier -v
2.8.4
✨ Done in 0.32s.
# 4
❯ yarn workspace @ywsbv/unrelated-package add uuid
yarn workspace v1.22.19
yarn add v1.22.19
[1/4] 🔍 Resolving packages...
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...
[4/4] 🔨 Building fresh packages...
success Saved lockfile.
success Saved 1 new dependency.
info Direct dependencies
info All dependencies
└─ uuid@9.0.0
✨ Done in 1.89s.
✨ Done in 2.05s.
# 5
❯ yarn why prettier
yarn why v1.22.19
[1/4] 🤔 Why do we have the module "prettier"...?
[2/4] 🚚 Initialising dependency graph...
[3/4] 🔍 Finding dependency...
[4/4] 🚡 Calculating file sizes...
=> Found "prettier@2.8.4"
info Has been hoisted to "prettier"
info Reasons this module exists
- "workspace-aggregator-3bec8ec4-773b-4509-8319-994d89d84355" depends on it
- Specified in "devDependencies"
- Hoisted from "_project_#prettier"
info Disk size without dependencies: "19.01MB"
info Disk size with unique dependencies: "19.01MB"
info Disk size with transitive dependencies: "19.01MB"
info Number of shared dependencies: 0
=> Found "@storybook/mdx1-csf#prettier@2.3.0"
info This module exists because "_project_#@ywsvb#package-with-transitive-prettier-dep#@storybook#addon-essentials#@storybook#addon-docs#@storybook#mdx1-csf" depends on it.
=> Found "@storybook/source-loader#prettier@2.3.0"
info This module exists because "_project_#@ywsvb#package-with-transitive-prettier-dep#@storybook#addon-essentials#@storybook#addon-docs#@storybook#source-loader" depends on it.
✨ Done in 0.26s.
# 6
❯ yarn prettier -v
yarn run v1.22.19
$ /Users/jonscheiding/Code/Personal/yarn-workspace-bin-version-issue/node_modules/.bin/prettier -v
2.3.0
✨ Done in 0.26s.
# 7
❯ yarn install
yarn install v1.22.19
[1/4] 🔍 Resolving packages...
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...
[4/4] 🔨 Building fresh packages...
✨ Done in 1.57s.
# 8
❯ yarn prettier -v
yarn run v1.22.19
$ /Users/jonscheiding/Code/Personal/yarn-workspace-bin-version-issue/node_modules/.bin/prettier -v
2.8.4
✨ Done in 0.26s.
Here's a repro: https://github.com/jonscheiding/yarn-workspace-bin-version-issue
This doesn't seem to affect just the .bin directory ... I created the following script in my repo:
console.log(require("prettier").version)
Running this at steps 3, 6 and 8 above produces the same version number that yarn prettier -v
did.
My monorepo has a new version of typescript hoisted to the root:
But I'm surprised to find that the version of
tsc
insidenode_modules/.bin
is an older version from a random transitive dependency:Instead, I expect that
node_modules/bin/tsc
points tonode_modules/typescript/bin/tsc
. This seems buggy to me, is this expected behaviour?