You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This feature is important to have in this repository; a contrib plugin wouldn't do
Describe the user story
As a consultant working with many different companies and projects using yarn, it has been difficult to migrate from the "checked in Yarn version" (.yarnrc.yml's yarnPath setting) to corepack. When migrating to corepack, users who have not enabled corepack can accidentally use global Yarn Classic and they receive no warning about it.
Checked In Yarn Version referenced by yarnPath
I'm using yarn set version 3.6.4 to show how this worked in Yarn Berry v3 when checking in the release to the repo.
Source:
> docker run -it --rm --entrypoint bash node:20.9.0
root@2d0e84fe9c26:/# yarn --version
1.22.19
root@2d0e84fe9c26:/# mkdir test-project
root@2d0e84fe9c26:/# cd test-project/
root@2d0e84fe9c26:/test-project# npm init -y
root@2d0e84fe9c26:/test-project# yarn set version 3.6.4
➤ YN0000: Retrieving https://repo.yarnpkg.com/3.6.4/packages/yarnpkg-cli/bin/yarn.js
➤ YN0000: Saving the new release in .yarn/releases/yarn-3.6.4.cjs
➤ YN0000: Done in 1s 7ms
root@2d0e84fe9c26:/test-project# cat .yarnrc.yml
yarnPath: .yarn/releases/yarn-3.6.4.cjs
I'm only writing the packageManager key in package.json. Currently, yarn set version <VERSION> will only write the packageManager key if the local machine has corepack already enabled.
Even in the test-project, where the packageManager key is set to yarn@4.0.1, global yarn still wins. This is different than the behavior when the release is checked in.
Official node images have global yarn classic and corepack disabled by default. It is challenging to assume that the packageManager key will do the right thing. You have to extend the official image to remove global yarn and/or enable corepack.
yarn set version <VERSION> makes global assumptions based on one developer's machine. If I have corepack enabled and run yarn set version berry, yarn does not write the release to the repo. In this case, yarn is making a global assumption that my CI environment, runtime container, other developer's machines, etc. will also have corepack enabled.
Yarn Classic does not warn you that you're intended to be using Yarn Berry. If I'm in a scenario where packageManager is set to a Yarn Berry version, Yarn Classic will run without warning or erroring. Most users will be unaware that there could be incompatibilities.
Node version managers (asdf, nvm) require corepack to be enabled for each Node version. Since corepack enable overwrites the yarn binary, it must be run for each version of Node you have installed via a Node Version Manager. Therefore, when switching around between projects using different versions of Node, it's easy to forget that you need to run corepack enable. Since there's no warning, you can transparently/accidentally use global yarn instead of berry.
I want to be able to guarantee that all consumers running yarn commands are using the proper version. It appears that Yarn Classic can read .yarnrc.yml's yarnPath config and always run the the correct version. However it does not pay attention to the packageManager key in package.json.
Describe the solution you'd like
A new release of Yarn Classic that throws an error if package.json's packageManager key is set, but corepack is not enabled. If the release is checked in and referenced by yarnPath, the packageManager key is ignored.
Describe the drawbacks of your solution
I believe Yarn Classic has had its final release and is not intended to be released again.
This could be considered a major release of Classic since it could break people's installs that rely on classic. We could make it a very visible warning instead.
Describe alternatives you've considered
Have new versions of Yarn Berry warn if corepack is not enabled, no matter the settings currently used. This doesn't help Classic users, though.
We could create a new feature in Berry that reads package.json's packageManager version and compares it against its own version. If there's a mismatch it refuses to run. Again, doesn't help Classic users.
We could introduce a new key in .yarnrc.yml that requires corepack to be enabled in v4 and newer. If .yarnrc.yml's requireCorepack is set to true, we somehow verify for the user (see issue above RE: no corepack status command). Again, doesn't help Classic users.
We could try to push for the global yarn Classic binaries to be removed from the official Node image, and corepack to be enabled by default. Since corepack is experimental, it feels like this will be a hard sell.
Why not make it a plugin? Because it feels like a core feature of Yarn. If we're going to require people to use an experimental/disabled-by-default feature of node (corepack), we should do our best to help people configure their environment.
Describe the user story
As a consultant working with many different companies and projects using
yarn, it has been difficult to migrate from the "checked in Yarn version" (.yarnrc.yml'syarnPathsetting) tocorepack. When migrating tocorepack, users who have not enabledcorepackcan accidentally use global Yarn Classic and they receive no warning about it.Checked In Yarn Version referenced by
yarnPathI'm using
yarn set version 3.6.4to show how this worked in Yarn Berry v3 when checking in the release to the repo.Source:
✅ Global Yarn Classic
✅ Corepack
root@2d0e84fe9c26:/test-project# corepack enable root@2d0e84fe9c26:/test-project# yarn --version 3.6.4Corepack (v4 recommendation)
I'm only writing the
packageManagerkey inpackage.json. Currently,yarn set version <VERSION>will only write thepackageManagerkey if the local machine hascorepackalready enabled.Source:
❌ Global Yarn Classic
Even in the
test-project, where thepackageManagerkey is set toyarn@4.0.1, globalyarnstill wins. This is different than the behavior when the release is checked in.✅ Corepack
However, if I enable
corepack, the proper version is used.root@870c6624fa62:/test-project# corepack enable root@870c6624fa62:/test-project# yarn --version 4.0.1The Issue
The main issues I see are:
packageManagerkey will do the right thing. You have to extend the official image to remove global yarn and/or enablecorepack.yarn set version <VERSION>makes global assumptions based on one developer's machine. If I havecorepackenabled and runyarn set version berry,yarndoes not write the release to the repo. In this case,yarnis making a global assumption that my CI environment, runtime container, other developer's machines, etc. will also havecorepackenabled.packageManageris set to a Yarn Berry version, Yarn Classic will run without warning or erroring. Most users will be unaware that there could be incompatibilities.corepackto be enabled for each Node version. Sincecorepack enableoverwrites theyarnbinary, it must be run for each version of Node you have installed via a Node Version Manager. Therefore, when switching around between projects using different versions of Node, it's easy to forget that you need to runcorepack enable. Since there's no warning, you can transparently/accidentally use globalyarninstead of berry.I want to be able to guarantee that all consumers running
yarncommands are using the proper version. It appears that Yarn Classic can read.yarnrc.yml'syarnPathconfig and always run the the correct version. However it does not pay attention to thepackageManagerkey inpackage.json.Describe the solution you'd like
A new release of Yarn Classic that throws an error if
package.json'spackageManagerkey is set, butcorepackis not enabled. If the release is checked in and referenced byyarnPath, thepackageManagerkey is ignored.Describe the drawbacks of your solution
corepackis enabled. There's nocorepack statusthat easily verifies thatcorepackis enabled (How can I detect if corepack is already enabled? nodejs/corepack#113).Describe alternatives you've considered
corepackis not enabled, no matter the settings currently used. This doesn't help Classic users, though.package.json'spackageManagerversion and compares it against its own version. If there's a mismatch it refuses to run. Again, doesn't help Classic users..yarnrc.ymlthat requirescorepackto be enabled in v4 and newer. If.yarnrc.yml'srequireCorepackis set totrue, we somehow verify for the user (see issue above RE: nocorepack statuscommand). Again, doesn't help Classic users.yarnClassic binaries to be removed from the official Node image, and corepack to be enabled by default. Sincecorepackis experimental, it feels like this will be a hard sell.corepack), we should do our best to help people configure their environment.