corepack
corepack copied to clipboard
Usage Error: This project is configured to use <pkgmgr>
One of the biggest problems I have today with Corepack is the Usage Error: This project is configured to use <pkgmgr>.
This happens when I run npm i -g vercel@latest in a project that is configured to use yarn or pnpm. This seems a little too strict because the global flag (-g) is not scoped to my current project.
Similarly, vercel dev will shell out to npm or npx and corepack being enabled could block it from working properly, even if the system has npm installed.
While I think the intention is good (catch accidental typos), I think this shouldn't be the default behavior because it is too restrictive. Perhaps making this strict mode be opt-in would help Corepack go stable (see #104).
Or it could spawn a prompt: You are running a command the uses <pkgmng> in a directory configured to use <pkgmng>. Do you want to continue?.
I would also like to be able to run things like yarn --version or npm --version in a situation where corepack is enabled. This early UsageError prevents me from doing that. While debugging @nathanhammond and I noticed that config.json contains an allowlist of commands that are passed through: https://github.com/nodejs/corepack/blob/312d9ea6f107ef05c7e8955538b9abd9f857f8a6/sources/main.ts#L46-L55
I'm not sure if my case is a good use case for this config, but may be a good place to start?
Or it could spawn a prompt:
I think a prompt would be annoying and cause more problems because you need a way to pass --yes to corepack without it passing --yes to the underlying package manager. Maybe a warning would be sufficient, but the hard block is just too much of a breaking change.
The only thing that might be safe to hard block is <pkg> install. So perhaps the allowlist needs to be inverted to a denylist so most commands can be allowed.
I think a prompt would be annoying and cause more problems because you need a way to pass
--yesto corepack without it passing--yesto the underlying package manager.
Using an env variable would be more practical than a --yes flag IMO.
I think an env var would be good.
I also think corepack needs to be smart enough to ignore -g or --global flags automatically.
One other use case I face while using it was that some external dependencies of my repo might have pre/postinstall scripts that calls yarn run something or npm run something. But if my repo is using pnpm, I set "packageManager" field to pnpm, and I enabled Corepack, my repo installation step (pnpm install) will fail on those pre/postinstall scripts.
Hey y'all, this particular feature (command invocation prevention) has been an absolutely tremendous thorn in our side for the entire time we've been using corepack.
In that time this feature has:
- required us to rework the entirety of our CI setup
- broken our local development workflow for debugging
- required manual local changes to our provided sample code (which doesn't specify
packageManagerbecause they're intended to be agnostic) prior to being able to test them
We find ourselves regularly using corepack disable (to expose a global version in $PATH listed behind it) to sidestep this issue. This happens because our tool (vercel/turborepo) must test against each package manager. We would hope that corepack would make it easy to support our needs of regularly switching package managers, but our experience has been that global installs (though more configuration up front) have allowed us to sidestep this one particular feature and make our development experience much smoother.
I hypothesize that we're going to see more and more of this as CI and PaaS vendors begin to roll out tooling to support corepack.
I would like to see exploration of different ways to constrain this behavior:
- Workspace awareness. You're running this command in a place where the closest "find up"
package.jsondoes not specifypackageManager. If the current package can be detected as a workspace of a parentpackage.jsonthat does specify apackageManager, throw an error. If not, log a warning about not specifyingpackageManagerand proceed. - Significant expansion of allow/deny lists to enable things like existence checks with
-v,npm config set registry footo run to completion. There exists a subset of commands that are going to be safe and/or compatible. - Opt in by specifying
packageManagerin only the closestpackage.json?
This comment is at least partially wrong; corepack checks to make sure there is not an ancestor node_modules directory. It may fail if for some reason a user isn't using node_modules as their require path (again making vercel/turborepo's workspaces setup a pain) but it's not a catastrophically bad situation.
~~Worth mentioning, esbuild and turbo both will encounter @kenrick95's noted issue:~~
~~https://github.com/vercel/turborepo/blob/add338a8d664544118178175281059878acd8fe6/packages/turbo/install.js#L120-L123~~
~~https://github.com/evanw/esbuild/blob/41c45af627cd72e86e6389434547d3d9a15b4ab2/lib/npm/node-install.ts#L97-L98~~
~~We can (and will) adjust our install method for future versions but we can't forcibly move everybody off of old versions.~~