Skip to content

Commit bba2c78

Browse files
authored
fix(cli): use project Node.js version for pnpm/yarn shim dispatch (#564)
Package managers like pnpm/yarn were using the install-time Node.js version instead of resolving from the project context (engines.node, .node-version, etc.), causing "Unsupported engine" warnings when the project requires a different Node version.
1 parent 0bfcc90 commit bba2c78

5 files changed

Lines changed: 50 additions & 4 deletions

File tree

crates/vite_global_cli/src/shim/dispatch.rs

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ use crate::commands::env::{
2424
/// directly using the current PATH (passthrough mode).
2525
const RECURSION_ENV_VAR: &str = "VITE_PLUS_TOOL_RECURSION";
2626

27+
/// Package manager tools that should resolve Node.js version from the project context
28+
/// rather than using the install-time version.
29+
const PACKAGE_MANAGER_TOOLS: &[&str] = &["pnpm", "yarn"];
30+
31+
fn is_package_manager_tool(tool: &str) -> bool {
32+
PACKAGE_MANAGER_TOOLS.contains(&tool)
33+
}
34+
2735
/// Main shim dispatch entry point.
2836
///
2937
/// Called when the binary is invoked as node, npm, npx, or a package binary.
@@ -156,11 +164,31 @@ async fn dispatch_package_binary(tool: &str, args: &[String]) -> i32 {
156164
}
157165
};
158166

159-
// Get the Node.js version that was used to install this package
160-
let node_version = &package_metadata.platform.node;
167+
// Determine Node.js version to use:
168+
// - Package managers (pnpm, yarn): resolve from project context so they respect
169+
// the project's engines.node / .node-version, falling back to install-time version
170+
// - Other package binaries: use the install-time version (original behavior)
171+
let node_version = if is_package_manager_tool(tool) {
172+
let cwd = match current_dir() {
173+
Ok(path) => path,
174+
Err(e) => {
175+
eprintln!("vp: Failed to get current directory: {e}");
176+
return 1;
177+
}
178+
};
179+
match resolve_with_cache(&cwd).await {
180+
Ok(resolution) => resolution.version,
181+
Err(_) => {
182+
// Fall back to install-time version if project resolution fails
183+
package_metadata.platform.node.clone()
184+
}
185+
}
186+
} else {
187+
package_metadata.platform.node.clone()
188+
};
161189

162190
// Ensure Node.js is installed
163-
if let Err(e) = ensure_installed(node_version).await {
191+
if let Err(e) = ensure_installed(&node_version).await {
164192
eprintln!("vp: Failed to install Node {}: {e}", node_version);
165193
return 1;
166194
}
@@ -175,7 +203,7 @@ async fn dispatch_package_binary(tool: &str, args: &[String]) -> i32 {
175203
};
176204

177205
// Locate node binary for this version
178-
let node_path = match locate_tool(node_version, "node") {
206+
let node_path = match locate_tool(&node_version, "node") {
179207
Ok(p) => p,
180208
Err(e) => {
181209
eprintln!("vp: Node not found: {e}");
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
22.12.0
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"name": "shim-pnpm-uses-project-node-version",
3+
"version": "1.0.0",
4+
"private": true
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
> vp env exec node -v # Node version resolved from .node-version
2+
v22.12.0
3+
4+
> vp env exec pnpm exec node -v # pnpm should use same project Node version
5+
v22.12.0
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"env": {},
3+
"commands": [
4+
"vp env exec node -v # Node version resolved from .node-version",
5+
"vp env exec pnpm exec node -v # pnpm should use same project Node version"
6+
]
7+
}

0 commit comments

Comments
 (0)