Consider calling yarn and pnpm with corepack
- [ ] I'd be willing to implement this feature (contributing guide)
Description
Some users may not have "installed" yarn or pnpm by running corepack enable, so when Lerna runs scripts using one of those, they get an error that yarn or pnpm can't be found.
> NX Command failed: yarn --version
There's this error higher up above it:
Error: Cannot find module 'D:\src\lume+lume\node_modules\yarn\bin\yarn.js'
at Module._resolveFilename (node:internal/modules/cjs/loader:1048:15)
at Module._load (node:internal/modules/cjs/loader:901:27)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:83:12)
at node:internal/main/run_main_module:23:47 {
If the project has Yarn configured, then this works when running it manually:
PS D:\src\lume+lume> corepack yarn --version
3.6.4
The corepack executable ships with Node.js, and corepack yarn and corepack pnpm work out of the box, and I bet this would work consistently and avoid the above issue (I'm not exactly sure what's the problem).
As for yarn, installing it as a local dev dependency doesn't work, due to Yarn relying on codepack, with the version on in the npm registry being old.
Not sure about pnpm, but if the latest is in the npm registry, then a library author could make it a dev dependency that would work fine.
Motivation
This is beneficial because things would just work for new contributors of a project.
As an example, I have scripts in package.json for getting started with a monorepo project, f.e. by running npm run link which uses corepack yarn install to bootstrap all packages. But subsequent Lerna commands fail.
I could tell people to run corepack enable. I could also try to automate that, but it could interfere with someone else's flow (EDIT: requires sudo or admin, so not very easy in Windows).
Suggested Implementation
Replacing yarn with corepack yarn, same with pnpm, should do the trick I think. corepack * automatically picks up and uses the project-configured package manager version from package.json, which in some ways is similar to a local install.
Alternate Implementations
I could tell people to run corepack enable. I could also try to automate that, but it could interfere with someone else's flow.
On second thought, that'll be difficult, it requires sudo/admin by default.
Apparently it is more complicated that that! I ran corepack enable, so yarn --version in PowerShell shows the latest version.
I missed that the output before the above NX error shows this:
Error: Cannot find module 'D:\src\lume+lume\node_modules\yarn\bin\yarn.js'
at Module._resolveFilename (node:internal/modules/cjs/loader:1048:15)
at Module._load (node:internal/modules/cjs/loader:901:27)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:83:12)
at node:internal/main/run_main_module:23:47 {
So although yarn --version works when I call it in PowerShell, it still doesn't work when Lerna tries.
This is my first time on Lerna v7 with Yarn. Before this, I was using Lerna 4 with npm.
But now that I've upgraded, I don't have npmClient set but Lerna seems to want to use Yarn as hinted by the NX yarn --version output.
After I set npmClient: "npm" based on the docs, I still see the same yarn --version error, which makes it seem like the option is not being honored by Lerna. How would I force Lerna to use NPM instead of Yarn (now that I've switched to Yarn for repo install+linking)?
Ok I discovered that, in Windows only, it will not fail on the yarn command if I start lerna with yarn. For example, if I have a lerna command in a pkg.json script like so:
"build:all": "lerna run build"
then if I run npm run build:all I get the yarn --version failure. If I run yarn build:all then it the failure is gone.
EDIT: nevermind, something changes, no idea what, and now yarn build:all does not have the error either. Arg.
^ That commit fixes the issue on the lume project.
Hi @trusktr , I'm glad you found a solution to the issue you were facing. As for the corepack suggestion - corepack is still listed as an experimental feature of node and so we couldn't replace all usages of yarn ... with corepack yarn ... by default. Though this is something we could consider in the future.
In the meantime (if we can't use corepack), it looks like Lerna tries to use the wrong version of Yarn, not the one specified by corepack config in package.json (which is the way Yarn tells everyone to install Yarn, so not entirely experimental from their perspective).
Take a look at the findings here:
- https://github.com/yarnpkg/berry/issues/5800#issuecomment-1768340567
Thanks for the additional context. If Yarn is recommending it, then there's a good chance Lerna should support it. If I recall correctly, pnpm supports corepack as well. I'll bring it up with the team.
@fahslaj I guess this issue can be closed since your PR #3877 got released
@fahslaj what about runScript should it also be executed with corepack? It might have been missed to also use execPackageManager, should it?
https://github.com/lerna/lerna/blob/2ba1a0cfb1e88f462f07aaf71f94290b9fc2d94a/libs/core/src/lib/npm-run-script.ts#L7-L14