fix: support standalone pnpm binary in postinstall (#151)

Postinstall assumed `npm_execpath` always points to pnpm's JS entry and
invoked it via `node $npm_execpath`. When pnpm is installed as a
standalone binary (e.g. `@pnpm/exe` via mise / volta), `npm_execpath`
points to an ELF/Mach-O/PE executable and Node fails with
"Invalid or unexpected token" parsing the binary as JS.

Branch on the executable's extension: keep wrapping `.js`/`.cjs`/`.mjs`
entries with `node`, but spawn other paths directly so standalone pnpm
binaries work too.

Co-authored-by: decker <decker502@qq.com>
This commit is contained in:
decker 2026-04-30 17:34:05 +08:00 committed by GitHub
parent 4ec1b4dc48
commit 6b6e345ca4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -1,5 +1,5 @@
import { spawnSync } from "node:child_process";
import { dirname, resolve } from "node:path";
import { dirname, extname, resolve } from "node:path";
import { fileURLToPath } from "node:url";
const scriptDir = dirname(fileURLToPath(import.meta.url));
@ -12,10 +12,15 @@ const buildTargets = [
"tools/dev",
];
const jsExtensions = new Set([".js", ".cjs", ".mjs"]);
function resolvePackageManagerInvocation() {
const pnpmExecPath = process.env.npm_execpath;
if (pnpmExecPath != null && pnpmExecPath.length > 0) {
return { argsPrefix: [pnpmExecPath], command: process.execPath };
if (jsExtensions.has(extname(pnpmExecPath).toLowerCase())) {
return { argsPrefix: [pnpmExecPath], command: process.execPath };
}
return { argsPrefix: [], command: pnpmExecPath };
}
return { argsPrefix: [], command: process.platform === "win32" ? "pnpm.cmd" : "pnpm" };