feat: support pnpm v12, which is distributed as a native executable - #887
Open
zkochan wants to merge 1 commit into
Open
feat: support pnpm v12, which is distributed as a native executable#887zkochan wants to merge 1 commit into
zkochan wants to merge 1 commit into
Conversation
Starting with v12, the `pnpm` package on npm only ships placeholders for its binaries: the actual platform-specific executable lives in a companion `@pnpm/exe.<platform>` package (pinned in the `optionalDependencies` of the main package), and a `preinstall` script copies it over the placeholders. Since Corepack never runs lifecycle scripts, it now replicates their effect for package manager versions whose config defines `nativePackages`: it downloads the companion package for the current platform, verifies its signature and integrity, and hardlinks its executable over each placeholder. The executable adapts its behavior to the name it was invoked under, which keeps the `pnpx` alias working. Native executables cannot be loaded into the current Node.js process like the JavaScript-based package managers, so they are spawned as a child process instead. Installs of pnpm >=12 performed by previous Corepack releases recorded binary paths that don't exist; such installs are detected and redone. Fixes: nodejs#873 Refs: nodejs#775 Refs: pnpm/pnpm#13018 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Author
|
First I wanted to add support for yarn 6 as well but then I have found out they don't recommend corepack for yarn anymore. |
Contributor
|
Hi @zkochan Thanks for the PR! I tested it locally and it looks good to me. 🚀 Hopefully a maintainer will be able to review soon! $ corepack use pnpm@next-12
Installing pnpm@12.0.0-rc.1 in the project...
Already up to date
Done in 4.6s using pnpm v12.0.0-rc.1
Yarn 6 is moving to Yarn Switch |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes: #873
Refs: #775
Refs: pnpm/pnpm#13018
Problem
Starting with v12, pnpm is a native executable (a Rust port). The
pnpmpackage on npm only ships shebang-less placeholders for its binaries; the actual platform-specific executable lives in a companion@pnpm/exe.<platform>package (pinned in theoptionalDependenciesof the main package), and apreinstalllifecycle script copies it over the placeholders. Corepack neither runs lifecycle scripts nor installsoptionalDependencies, socorepack use pnpm@next-12currently fails withMODULE_NOT_FOUND(#873). pnpm won't be adding a backward-compatible JS shim, as it would defeat the point of the native port (see pnpm/pnpm#13018 (comment)).Solution
This PR replicates the effect of pnpm's install script inside Corepack, driven by a new optional
nativePackagesfield inconfig.jsonrange definitions (mapping${platform}-${arch}[-musl]keys to{package, bin}):package.json'soptionalDependencies, downloads the companion package for the current platform (with the same signature + integrity verification as the main tarball), and hardlinks its executable over each placeholder bin. The pnpm executable adapts its behavior to the name it was invoked under, which is what keepspnpx(=pnpm dlx) working.Module.runMain, so it is spawned as a child process, with signal forwarding and exit-code propagation../bin/pnpm.mjs). Such installs are detected on reuse and silently redone, so users don't need to clearCOREPACK_HOMEby hand.The libc detection (glibc vs musl via
process.report) and the platform table mirror the logic of pnpm's owninstall.js.Testing
pnpxalias, signature verification of the companion package, and cache reuse (skipped on Windows, where the fake native executable — a shell script — cannot be spawned).pnpm@12.0.0-rc.1:corepack pnpm --version,corepack pnpm install, andcorepack pnpx --help(correctly maps topnpm dlx) all work;pnpm/pnpxbins are hardlinks of the same 38 MB native executable;🤖 Generated with Claude Code