jdx / mise

dev tools, env vars, task runner
https://mise.jdx.dev
MIT License
9.17k stars 248 forks source link

Support for `corepack enable npm` #1863

Open akineko opened 5 months ago

akineko commented 5 months ago

Thank you for the excellent tool. I'm not good at English, so the text might be difficult to read. Please understand.

Background

Corepack has a feature that throws an error when a different tool than the one specified in the packageManager field of package.json is used. This feature does not work with Node.js installed by mise.

package.json

{
  "packageManager": "pnpm@8.15.6",
}

yarn install failed.

$ corepack enable yarn
$ yarn install

Usage Error: This project is configured to use pnpm

$ yarn ...

But, npm install succeeds.

$ npm install

added 6 packages, removed 71 packages, and audited 4761 packages in 11s

362 packages are looking for funding
  run `npm fund` for details

Other run results.

$ corepack npm install

Usage Error: This project is configured to use pnpm

$ npm ...
$ corepack enable npm
Internal Error: EINVAL: invalid argument, readlink '/home/akineko/.local/share/mise/installs/node/20.12.1/bin/npm'
Error: EINVAL: invalid argument, readlink '/home/akineko/.local/share/mise/installs/node/20.12.1/bin/npm'
$ ls -l ~/.local/share/mise/installs/node/20.12.1/bin/
total 95696
lrwxrwxrwx 1 akineko akineko       45 Apr  3 11:39 corepack -> ../lib/node_modules/corepack/dist/corepack.js
-rwxr-xr-x 1 akineko akineko 97981176 Apr  3 11:39 node
-rwxr-xr-x 1 akineko akineko     1777 Apr  5 15:03 npm
lrwxrwxrwx 1 akineko akineko       38 Apr  3 11:39 npx -> ../lib/node_modules/npm/bin/npx-cli.js
lrwxrwxrwx 1 akineko akineko       41 Apr  5 16:01 pnpm -> ../lib/node_modules/corepack/dist/pnpm.js
lrwxrwxrwx 1 akineko akineko       41 Apr  5 16:01 pnpx -> ../lib/node_modules/corepack/dist/pnpx.js
lrwxrwxrwx 1 akineko akineko       41 Apr  5 15:09 yarn -> ../lib/node_modules/corepack/dist/yarn.js
lrwxrwxrwx 1 akineko akineko       44 Apr  5 15:09 yarnpkg -> ../lib/node_modules/corepack/dist/yarnpkg.js

Proposal

If npm could be made a symbolic link, similar to npx, I predict that corepack enable npm would become usable and the issue would be resolved.

jdx commented 5 months ago

If npm could be made a symbolic link

the problem with this is that it's currently a shim that automatically runs mise reshim when global packages are installed so we can't really get rid of that.

wycats commented 1 week ago

I really like mise's reframing of "legacy version files" to "idiomatic" version files.

Where asdf's framing was focused entirely on compatibility (and wasn't forward-looking at all), the "idiomatic" framing seems to open the door to adding support for newer ecosystem idioms.

Since corepack has become the Node ecosystem standard for communicating Node-specific tools via package.json, it would be awesome if Mise added support for corepack. This could be accomplished either by interpreting the package.json declaration as an "idiomatic" version file.

Integrating directly with the corepack workflow would also be awesome, but that's harder and I think we could get a lot of mileage from simply interpreting the fields used by corepack.

As an aside, I never understood why asdf doesn't already treat engines in package.json as a source of idiomatic version information. I'm a noob to this space and there's probably an obvious reason.

https://nodejs.org/api/packages.html#packagemanager

jdx commented 1 week ago

Since corepack has become the Node ecosystem standard for communicating Node-specific tools via package.json, it would be awesome if Mise added support for corepack. This could be accomplished either by interpreting the package.json declaration as an "idiomatic" version file.

It's not clear what this means practically, is it essentially just that we would run corepack enable [packagemanager.name] && corepack install [packagemanager.name]@[packagemanager.version] when installing node?

I think we could do this, however I am a bit concerned with presenting this to the user as it has a limitation with what would be possible today without significant changes. mise does support "tool options" which seems like the best place to add this metadata, these modify what happens when tools are installed, e.g.:

[tools]
node = {version="20", corepack="pnpm@1"}

The trouble here is this affects all installations of node@20. So if you had another project with this configuration:

[tools]
node = {version="20", corepack="yarn@1"}

Then yarn wouldn't necessarily be used in the case you installed the one with the pnpm config first.

Of course this problem isn't limited to node, but right now we barely used this feature in mise so it hasn't been an issue but if we added corepack it would get used a lot more heavily.

One solution to this would be for project tools to be installed locally to a .mise directory inside the project like node_modules, but that would be a pretty major change to mise with its own set of drawbacks.