You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Use the package manager version specified by the project, but still allow other package manager invocations #195
At time of writing, at 0.14.0 there is COREPACK_ENABLE_STRICT=0 , which disables this check completely and will always use the fallback version of package managers. However, there should be a middle ground, to use the package manager version specified by the project, but does not throw error when other package manager is invoked.
Use case example:
globally, I prepared & activated pnpm@7.13.4 and yarn@1.22.19
there is a project, managed using pnpm@6.33.0 (specified in the "packageManager" field in package.json). However there are some external dependencies with pre/post-install scripts that calls "yarn build".
With the default configuration of Corepack, I cannot bootstrap the project at all, i.e. I cannot successfully run pnpm install. This is because invocation of yarn inside that repo will fail due to "Usage error", i.e. #157)
However, with COREPACK_ENABLE_STRICT=0, I still cannot bootstrap the project as expected, because now pnpm install will use the fallback/global pnpm (7.13.4) instead of the version specified by the repo (6.33.0)
Proposal:
When I set COREPACK_ENABLE_STRICT=0
running pnpm in that project should still use the version specified by the repo (6.33.0) instead of the fallback/global version.
running yarn in that project should use the global/fallback version
The original name for the env variable was something like COREPACK_IGNORE_PACKAGE_JSON, as I figured it would be convenient to give a way for users to skip the package.json parsing entirely (e.g. if you have an enormous package.json file, you might prefer to specify the version yourself instead of having Corepack reparse your JSON file every time).
That being said, I agree that your use case seems valid, and Corepack should default to make it work, or at least provide a way to make it work.
Yep, I also thought that COREPACK_ENABLE_STRICT would only affect the package manager check, not the version itself 🤔
There's probably still time to change it since we're experimental, especially since the current behaviour isn't obvious.
I really wish JS package managers had adopted a similar pattern as it would circumvent this problem entirely.
In Yarn you can use run build (instead of yarn run build), the original intent being that other packages managers could implement run as well and thus avoid users having to hardcode the package managers' name just for running scripts.
Unfortunately afaik only Yarn implements it (we didn't advertise it much, to be fair).
Reacted by Antoine du Hamel, Kenrick, Steven, Michael Kriese and Brody McKee
We've hit this issue too. In our case, a package we rely on has an install script that looks like this:
{
"install": "restore-from-cache || npm run rebuild",
}
We want to use Corepack to help engineers and tooling use the right package manager and version to interact with the repo, but checking invocations by packages feels too strict. Ideally, packages would be able to use "run" or "corepack run" instead (#57), but that could take a long time to filter through the ecosystem.
We don't want to have our engineers set COREPACK_ENABLE_STRICT to 0 as we feel that negates the benefits of Corepack.
Open an issue on their repo asking them to consider using $npm_execpath run build instead of npm run build? I'm not saying that it's not worth fixing the issue on Corepack side, but that seems it should be easy enough for them to fix that.
The right package manager is always the one managing the whole project. Hardcoding one is always a bad idea, because it runs afoul of the settings define for the project (for example yarn run foo wouldn't read the .npmrc, and the other way around) in the best case, and literally doesn't work in the worst case (npm run foo would crash on PnP installs).
The script can already ignore any settings set by the outer project by passing NPM_CONFIG_ env vars to another npm run invocation. It seems like the bad idea is using a package manager that the author didn't intend on any project at any level of the dep graph. I see tho that taking any of these ideas to their logical extension leads to an inevitable conclusion that wouldn't be productive to discuss, so I'll drop the topic.
There isn't a "correct" solution here if we want to maintain the packageManager matching check. There's just a long list of options with varying degrees of pragmatic behavior.
Options:
Drop the corepack check entirely.
Drop the corepack check when invoked by another process.
Push the solution to consumers via COREPACK_ENABLE_STRICT=0 <whatever> install
Push the solution to package authors via a solution that approximates $npm_execpath or npm run foo || yarn run foo || pnpm run foo
Of these, Option 2 seems like it may be a good pragmatic balance. Anything that requires behavior change is likely to prevent adoption.
@aduh95 this is well outside the scope of work I should be focusing on right now (you may have seen my team's big announcement yesterday) so I won't have any opportunity to get to this.
Activity
styfle commentedon Oct 11, 2022
Agreed, that is how I expected it to work.
This seems like a bug.
aduh95 commentedon Oct 11, 2022
The original name for the env variable was something like
COREPACK_IGNORE_PACKAGE_JSON, as I figured it would be convenient to give a way for users to skip thepackage.jsonparsing entirely (e.g. if you have an enormouspackage.jsonfile, you might prefer to specify the version yourself instead of having Corepack reparse your JSON file every time).That being said, I agree that your use case seems valid, and Corepack should default to make it work, or at least provide a way to make it work.
Slightly off-topic, but in PHP land, you can use
@buildinstead ofcomposer build(see https://getcomposer.org/doc/articles/scripts.md#referencing-scripts), I really wish JS package managers had adopted a similar pattern as it would circumvent this problem entirely.arcanis commentedon Oct 11, 2022
Yep, I also thought that
COREPACK_ENABLE_STRICTwould only affect the package manager check, not the version itself 🤔There's probably still time to change it since we're experimental, especially since the current behaviour isn't obvious.
In Yarn you can use
run build(instead ofyarn run build), the original intent being that other packages managers could implementrunas well and thus avoid users having to hardcode the package managers' name just for running scripts.Unfortunately afaik only Yarn implements it (we didn't advertise it much, to be fair).
mrmckeb commentedon Oct 14, 2022
We've hit this issue too. In our case, a package we rely on has an
installscript that looks like this:{ "install": "restore-from-cache || npm run rebuild", }We want to use Corepack to help engineers and tooling use the right package manager and version to interact with the repo, but checking invocations by packages feels too strict. Ideally, packages would be able to use "run" or "corepack run" instead (#57), but that could take a long time to filter through the ecosystem.
We don't want to have our engineers set
COREPACK_ENABLE_STRICTto0as we feel that negates the benefits of Corepack.aduh95 commentedon Oct 14, 2022
Open an issue on their repo asking them to consider using
$npm_execpath run buildinstead ofnpm run build? I'm not saying that it's not worth fixing the issue on Corepack side, but that seems it should be easy enough for them to fix that.styfle commentedon Oct 14, 2022
$npm_execpathdoesn't work on Windows #57 (comment)ljharb commentedon Oct 14, 2022
Isn't the "right" package manager for a package with scripts referencing npm, npm?
arcanis commentedon Oct 14, 2022
The right package manager is always the one managing the whole project. Hardcoding one is always a bad idea, because it runs afoul of the settings define for the project (for example
yarn run foowouldn't read the .npmrc, and the other way around) in the best case, and literally doesn't work in the worst case (npm run foowould crash on PnP installs).ljharb commentedon Oct 14, 2022
The script can already ignore any settings set by the outer project by passing NPM_CONFIG_ env vars to another
npm runinvocation. It seems like the bad idea is using a package manager that the author didn't intend on any project at any level of the dep graph. I see tho that taking any of these ideas to their logical extension leads to an inevitable conclusion that wouldn't be productive to discuss, so I'll drop the topic.nathanhammond commentedon Oct 24, 2022
There isn't a "correct" solution here if we want to maintain the
packageManagermatching check. There's just a long list of options with varying degrees of pragmatic behavior.Options:
COREPACK_ENABLE_STRICT=0 <whatever> install$npm_execpathornpm run foo || yarn run foo || pnpm run fooOf these, Option 2 seems like it may be a good pragmatic balance. Anything that requires behavior change is likely to prevent adoption.
aduh95 commentedon Oct 26, 2022
@nathanhammond would you like to send a PR? That seems like a reasonable approach to me.
merceyz commentedon Oct 26, 2022
If I'm reading the suggestion correctly then I disagree, disabling the check defeats one of the "goals" of Corepack.
nathanhammond commentedon Oct 27, 2022
@merceyz I'm not attached to anything and I specifically note:
The reality is that
corepackisn't ecosystem compatible, as demonstrated by the package I submitted an issue to (linked in this thread).You're proposing we remain ecosystem incompatible which is a fine choice, but ensures that adoption of
corepackwill be limited.In general: we collectively wrote the guidelines you cite, and we can always change them to improve the experience of using
corepack.nathanhammond commentedon Oct 27, 2022
@aduh95 this is well outside the scope of work I should be focusing on right now (you may have seen my team's big announcement yesterday) so I won't have any opportunity to get to this.