volta-cli / volta

Volta: JS Toolchains as Code. ⚡
https://volta.sh
Other
10.98k stars 230 forks source link

How to persist yarn version to `classic` #1689

Open garysassano opened 7 months ago

garysassano commented 7 months ago

I installed yarn 4.0.2 using volta, but whenever I execute yarn set version classic, it reverts back to version 4.0.2 the next time I launch my IDE.

favna commented 7 months ago

Any particular reason you want to stick to Yarn classic? Yarn berry is much faster and much more feature rich. Yarn classic is also deprecated and not recommended for use anymore by the Yarn team. If by chance you want to use Yarn classic because of pnp mode that Yarn berry had, you can very simply configure Yarn to use node_modules with yarn config set nodeLinker node-modules, see https://yarnpkg.com/configuration/yarnrc#nodeLinker. Once you have configured the nodeLinker, you probably also want to enable global cache with yarn config set enableGlobalCache true (https://yarnpkg.com/configuration/yarnrc#enableGlobalCache) and once that is done Yarn berry will function just like Yarn classic for how it installs dependencies except for all the advantages of speed that Yarn berry brings with it.

garysassano commented 7 months ago

@favna No particular reason, other than not using yarn at all if not for building some open-source projects and all those projects are using classic version.

cawolfdev commented 1 month ago

For me, about 90% of work projects use yarn 1; it's still mandated for most projects.

Choosing to use yarn 3 would mean opting out of all support for servers, installations, compliance, integrations, and automatic update scripts provided by build, release, infrastructure, and qa divisions.

Some smaller teams with limited internal only deliverables have upgraded to yarn 3, but have met with many difficulties in patching needed tools and scripts, and have fought with existing tooling. I laud their architects goal of modernizing the stack, and to treat the non-US developers who use Windows as first class, vs the traditional "mac-first" US-Centric approach. Until yarn 3 is proven to work seamlessly, I doubt a successful push will emerge to upgrade tens of hundreds of utilities to work seamlessly with npm/pnpm/yarn1/yarn3; as the hundred or so projects migrate yarn versions.

charlespierce commented 1 month ago

Hi @garysassano! I'm not an expert in how Yarn works internally (yarn set version is a command provided by Yarn itself to manage the version)—I would expect that to write a file somewhere to persist the version, but if it's resetting when you restart your IDE / terminal, perhaps it's only setting something temporary.

Regardless, one solution could be to install version 1 with Volta (e.g. volta install yarn@1), so that it's used by default in projects that don't have a yarn configuration. Then if you happen to use a project that needs a more recent Yarn version, you can use either Volta's pinning (volta pin yarn@4) or yarn's own yarn set version to configure the individual project to use a newer version.

Would that work for your use case?

favna commented 1 month ago

I'm not an expert in how Yarn works internally (yarn set version is a command provided by Yarn itself to manage the version)—I would expect that to write a file somewhere to persist the version, but if it's resetting when you restart your IDE / terminal, perhaps it's only setting something temporary.

Yarn downloads a JavaScript file that is the whole Yarn package manager in minified form to the .yarn/releases folder. Yarn works on a per-project-specific version strategy similar to a tool like Gradle for the Java community. You have 1 global version which can be anything of 1.22.22 (classic) or any of the berry versions but that version matters very little because the project-specific version is always used.

Yarn knows to read the file from .yarn/releases/yarn-x.y.z.cjs because the path to it is configured in the .yarnrc..yml file (.yarnrc (properties format) for yarn classic, if you would use something like yarn set version 1.22.20 while your global toolchain is 1.22.22, a very niche scenario might I add). For example a .yarnrc.yml file might have a line like:

yarnPath: .yarn/releases/yarn-4.4.0.cjs

This is a great system because it ensures that if you have a large team of developers, or you're an open source developer who gets PRs from outsiders, that everyone uses the same package manager version which ensures that there are no inequalities in lockfile generation, module installation, plugin handling, etc.

[!NOTE] One final note regarding the file in .yarn/releases, Yarn recommends checking that into Git. This follows from the above paragraph explaining that it's beneficial to teams and users. Furthermore, if you do not check it in but you do check in the .yarnrc.yml file, Yarn will end up throwing a ENOENT error on a fresh clone because the file won't be there