Repository navigation
perf(pm): skip the npm --version spawn in npm projects - #3259
Conversation
In a project that uses npm, `vp run`, `vp list`, `vp outdated`, `vp install`, and the other package-manager commands first ran `npm --version` to learn the version of the npm on PATH. That starts Node.js one more time for every command. Two paths ran it: the default resolution (`resolve_npm_from_path`, which `vp run` also uses) and the system-first shim mode (`system_package_manager` in the global CLI). `npm --version` prints the `version` field of npm's own package.json. The npm on PATH normally links into its package (`bin/npm` -> `lib/node_modules/npm/bin/npm-cli.js`), so both paths read that manifest now. If the nearest package.json within four parents does not belong to npm (for example a version-manager shim, Corepack, or Windows `npm.cmd`), they run `npm --version` as before. The manifest belongs to the npm on PATH, not to the npm that ships with Node.js, so an npm in a separate global prefix keeps its own version. npm does not switch versions per project, so the value matches `npm --version`. pnpm, yarn, and bun do not change: `vp` resolves their version itself and runs `--version` only in system-first mode, and pnpm and yarn can switch to the version that the project selects before they answer. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
68dbcc6 to
fbc1817
Compare
|
CI flaky issue has been fixed in main branch, you can merge commit from main. 😭 |
|
This was a design left by me actually, I'll share some context:
I originally designed a Also, the current |
|
@liangmiQwQ I don't think this PR changes which npm version So in short, this PR is to imitate what |
|
@magurotuna Let me take care of the flaky ci 😢 |
Oh! I previously thought you are reading projects' package.json, sorry for misunderstanding! |
Summary
This PR saves about 110 ms on every
vp runand every package-manager command (vp install,vp add,vp list,vp outdated, and others) in npm projects by makingvpread the npm version from npm'spackage.jsoninstead of runningnpm --version.Benchmark
vp run noopvp listnoopis a script that runsnode -e 0. Mean of 30 runs on:Approach
vpneeds the npm version to build the right command line and thenpm_config_user_agentfor scripts. It rannpm --versionfor this, which starts Node.js and loads npm only to print theversionfield of npm's ownpackage.json. Reading that file directly skips the process.If the npm on
PATHdoes not resolve into npm's package (for example, a version-manager shim, Corepack, ornpm.cmdon Windows),vpstill runsnpm --version.This PR only affects npm cases. pnpm and yarn leave room for a similar speedup: in system-first mode,
vprunspnpm --versionoryarn --version, and the JavaScript builds (pnpm 11 and earlier, and yarn) answer slowly. However, pnpm and yarn can switch to the version that the project selects, so reading theirpackage.jsonwould not be correct. This is left for a follow-up.