Description
When a project's only Node.js version declaration is an existing .nvmrc, vp env pin lts should update that file by default. In Vite+ 0.3.1, it instead adds package.json#devEngines.runtime and leaves .nvmrc unchanged.
This turns one Node version declaration into two conflicting declarations. Vite+ immediately switches to the new devEngines.runtime value because it has higher priority, while nvm and CI jobs configured with node-version-file: .nvmrc still read the old version.
The requested behavior is to retain the project's existing version-management format when changing its pin. Implementation PR: #2676.
Reproduction
Reproduced with the published vp v0.3.1 binary on Linux x64 / WSL2, in a temporary directory with no dependencies or local Vite+ installation:
repro_dir="$(mktemp -d)"
cd "$repro_dir"
cat > package.json <<'JSON'
{
"name": "vp-pin-nvmrc-repro",
"private": true
}
JSON
printf '24.20.0\n' > .nvmrc
vp env current --json
vp env pin lts --no-install
cat .nvmrc
cat package.json
vp env current --json
--no-install only avoids pre-downloading the runtime. In this reproduction, lts resolved to 24.21.0.
Before pinning, vp env current --json reports:
{ "node": { "version": "24.20.0", "source": ".nvmrc" } }
The pin command reports:
✓ Pinned Node.js version to 24.21.0 (resolved from lts)
Updated devEngines.runtime in <repro>/package.json
.nvmrc still contains 24.20.0, while package.json now contains:
{
"name": "vp-pin-nvmrc-repro",
"private": true,
"devEngines": {
"runtime": {
"name": "node",
"version": "24.21.0",
"onFail": "download"
}
}
}
After pinning, vp env current --json reports:
{ "node": { "version": "24.21.0", "source": "devEngines.runtime" } }
The two JSON outputs above are excerpts containing the relevant fields.
Suggested solution
When .nvmrc is the existing, sole Node pin in the current project and no explicit --target is supplied:
- Update
.nvmrc to the resolved version (24.21.0 in this example).
- Leave
package.json unchanged and avoid creating another Node version declaration.
- Preserve an explicit
--target dev-engines choice for users who intentionally want that format. A --target nvmrc option could also make the choice explicit.
This would extend the existing compatibility-first behavior for .node-version. As a control, the same fixture with .node-version instead of .nvmrc, using vp env pin lts --no-install --force, updates .node-version and leaves package.json unchanged.
Alternative
Manually editing .nvmrc works, but bypasses the pin command. --target node-version creates a second version file, so it does not preserve the existing setup. Removing .nvmrc or migrating the project to another format can disrupt teammates and CI that still use it.
Additional context
Validations
Description
When a project's only Node.js version declaration is an existing
.nvmrc,vp env pin ltsshould update that file by default. In Vite+ 0.3.1, it instead addspackage.json#devEngines.runtimeand leaves.nvmrcunchanged.This turns one Node version declaration into two conflicting declarations. Vite+ immediately switches to the new
devEngines.runtimevalue because it has higher priority, while nvm and CI jobs configured withnode-version-file: .nvmrcstill read the old version.The requested behavior is to retain the project's existing version-management format when changing its pin. Implementation PR: #2676.
Reproduction
Reproduced with the published
vp v0.3.1binary on Linux x64 / WSL2, in a temporary directory with no dependencies or local Vite+ installation:--no-installonly avoids pre-downloading the runtime. In this reproduction,ltsresolved to24.21.0.Before pinning,
vp env current --jsonreports:{ "node": { "version": "24.20.0", "source": ".nvmrc" } }The pin command reports:
.nvmrcstill contains24.20.0, whilepackage.jsonnow contains:{ "name": "vp-pin-nvmrc-repro", "private": true, "devEngines": { "runtime": { "name": "node", "version": "24.21.0", "onFail": "download" } } }After pinning,
vp env current --jsonreports:{ "node": { "version": "24.21.0", "source": "devEngines.runtime" } }The two JSON outputs above are excerpts containing the relevant fields.
Suggested solution
When
.nvmrcis the existing, sole Node pin in the current project and no explicit--targetis supplied:.nvmrcto the resolved version (24.21.0in this example).package.jsonunchanged and avoid creating another Node version declaration.--target dev-engineschoice for users who intentionally want that format. A--target nvmrcoption could also make the choice explicit.This would extend the existing compatibility-first behavior for
.node-version. As a control, the same fixture with.node-versioninstead of.nvmrc, usingvp env pin lts --no-install --force, updates.node-versionand leavespackage.jsonunchanged.Alternative
Manually editing
.nvmrcworks, but bypasses the pin command.--target node-versioncreates a second version file, so it does not preserve the existing setup. Removing.nvmrcor migrating the project to another format can disrupt teammates and CI that still use it.Additional context
.nvmrcas a source for node version #2207 / feat: add support for.nvmrcas node version source #2244 added support for reading.nvmrc. This request concerns writing/updating the existing file duringvp env pin..node-versionandpackage.json, but does not consider.nvmrc..nvmrc,env pin, existing pins, and write-target selection, and did not find a report requesting this behavior.Validations