Repository navigation
fix(shim): move npm global links to the reinstalled Node.js version - #3283
mondaychen wants to merge 2 commits into
Conversation
When the active Node.js version changes, `npm install -g <pkg>` installs a new copy into the new Node.js npm prefix. The `~/.vite-plus/bin` link kept the old target because Vite+ replaced a link only when a different package owned it. The command then kept running the old version. Replace the link also when the same package owns it but the link does not point to the binary in the current npm bin dir, record the new Node.js version, and tell the user that the link moved. Fixes voidzero-dev#3279 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A dry run changes no files in the npm prefix, but the post-install hook still saw an existing binary in that prefix and could move the link to it. With the same package in two prefixes, `npm install -g --dry-run` into the older prefix moved the command back to the older version. Skip the post-install link step when npm's effective `dry-run` setting is on. A CLI flag wins; otherwise `npm config get dry-run` reports the value from the environment and npmrc. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
| return dry_run; | ||
| } | ||
| std::process::Command::new(npm_path.as_path()) | ||
| .args(["config", "get", "dry-run"]) |
There was a problem hiding this comment.
[P2] Preserve the install's configuration context in the dry-run query
The install runs with -g, but this probe omits global mode and the install's configuration-selection flags. From a child npm workspace, npm config get dry-run fails with ENOWORKSPACES, which unwrap_or(false) treats as a real install. With an active link to 2.0.0 and an older prefix containing the same package at 1.0.0, I reproduced npm_config_dry_run=true npm install -g --prefix <old-prefix> <local-v2-package> switching the active command to 1.0.0 even though npm left the old installation unchanged. Adding --global to the probe returns the correct true value.
The mismatch also works in reverse: a project .npmrc containing dry-run=true is ignored by install -g but read by this probe, so a real install gets no Vite+ link or BinConfig. An explicit --userconfig=<file> is also lost, allowing a dry run selected by that file to relink. Please query the setting with the same global mode and configuration selectors as the install, and add coverage for these contexts.
| if arg == "--dry-run" { | ||
| dry_run = Some(true); | ||
| } else if arg == "--no-dry-run" { | ||
| dry_run = Some(false); |
There was a problem hiding this comment.
[P2] Match npm's boolean argument parsing
npm consumes a following true or false token for a boolean option, but this loop assigns a value from the flag alone. With npm install -g <pkg> --dry-run false, npm performs a real install while this function returns Some(true), so Vite+ skips creating the global link. The reverse occurs with --no-dry-run false: npm enables dry-run, but Vite+ returns Some(false) and can redirect the active command to an older copy. I reproduced both failures with the PR binary. The supported --dry abbreviation also bypasses the guard. Please use npm's effective parsed value, or match its boolean-value, negation, and option-abbreviation rules before deciding whether to mutate links.
Summary
Fixes #3279.
When the active Node.js version changes,
npm install -g <pkg>installs a new copy into the new Node.js npm prefix. The~/.vite-plus/bin/<bin>link kept pointing to the old copy, because Vite+ replaced an existing npm link only when a different package owned it. npm reported success and Vite+ printed nothing, so the command kept running the old version.Now Vite+ also replaces the link when the same package owns it but the link does not point to the binary in the current npm bin dir. It records the new Node.js version in the BinConfig and prints a note:
A repeat install under the same Node.js version leaves the link and BinConfig unchanged and prints nothing new.
On Unix, the check compares the symlink target. On Windows, it checks the source path in the
.cmdwrapper thatcreate_bin_linkwrites.Tests
test_npm_reinstall_under_new_node_version_moves_link: two npm prefixes, one per Node.js version. It fails with the old condition and passes with this change. It also checks that a repeat install changes nothing.npm_global_install_node_version_relink(global flavor, Unix only, like the other npm link cases): install with Node.js 24, install again withVP_NODE_VERSION=26.12.1, remove the Node.js 24 copy, and run the command. The runner seeds the runtime folder from a shared cache, so each step sets a case-localNPM_CONFIG_PREFIXper Node.js version instead of writing into the runtime folder.npm_global*snapshot cases pass locally.cargo fmt --checkandclippy -p vp_global_cli --all-targets --deny warningspass. I could not compile thecfg(windows)branch locally.🤖 Generated with Claude Code