mirror of
https://github.com/pnpm/pnpm.git
synced 2026-06-27 09:25:24 -04:00
The published pacquet/@pnpm/pacquet and @pnpm/pnpr bins were #!/usr/bin/env node launchers that spawned the real native binary, so every invocation paid full Node startup (~170ms) on top of the ~30ms the binary needs. Ship the native binary as the bin instead, mirroring @pnpm/exe. bin/pacquet and bin/pnpr are published as non-executable placeholders, and an install.js preinstall replaces the placeholder with the platform native binary (hard link, copy fallback across filesystems, atomic temp-file + rename). On Windows it adds a .exe twin, overwrites the original-name file the existing shim points at, and repoints bin at the .exe (npm doesn't re-read package.json after preinstall). Binary selection resolves whichever @pacquet/* / @pnpm/pnpr.* package the package manager installed; the guarded process.report glibc probe only orders the linux glibc/musl pair for the --force both-installed case. A placeholder (not a launcher overwritten in place) is required because on Windows the shim is generated from the launcher's node shebang and would keep calling node; a placeholder has no shebang so the generated shim runs the file directly. Trade-off: no Node-launcher fallback. With build scripts blocked (--ignore-scripts, pnpm/Bun default) the bin stays a placeholder until allow-listed. The configDependencies install-engine path is unaffected: pnpm resolves and spawns the @pacquet/<platform>-<arch> native binary directly, never bin/pacquet. A stale comment in runPacquet.ts is corrected to match.