corepack icon indicating copy to clipboard operation
corepack copied to clipboard

Usage Error: This project is configured to use <pkgmgr>

Open styfle opened this issue 3 years ago • 2 comments

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).

styfle avatar Aug 07 '22 22:08 styfle

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?.

aduh95 avatar Aug 08 '22 09:08 aduh95

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?

mehulkar avatar Aug 09 '22 22:08 mehulkar

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.

styfle avatar Aug 10 '22 20:08 styfle

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.

Using an env variable would be more practical than a --yes flag IMO.

aduh95 avatar Aug 15 '22 07:08 aduh95

I think an env var would be good.

I also think corepack needs to be smart enough to ignore -g or --global flags automatically.

styfle avatar Aug 24 '22 02:08 styfle

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.

kenrick95 avatar Aug 25 '22 09:08 kenrick95

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 packageManager because 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.json does not specify packageManager. If the current package can be detected as a workspace of a parent package.json that does specify a packageManager, throw an error. If not, log a warning about not specifying packageManager and proceed.
  • Significant expansion of allow/deny lists to enable things like existence checks with -v, npm config set registry foo to run to completion. There exists a subset of commands that are going to be safe and/or compatible.
  • Opt in by specifying packageManager in only the closest package.json?

nathanhammond avatar Sep 01 '22 02:09 nathanhammond

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.~~

nathanhammond avatar Sep 01 '22 02:09 nathanhammond