Skip to content

Commit 06ed3dd

Browse files
committed
perf and refactor
1 parent 8ea9fed commit 06ed3dd

1 file changed

Lines changed: 40 additions & 43 deletions

File tree

crates/vite_global_cli/src/js_executor.rs

Lines changed: 40 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
66
use std::process::{ExitStatus, Output};
77

8+
use node_semver::{Range, Version};
89
use tokio::process::Command;
910
use vite_js_runtime::{
1011
JsRuntime, JsRuntimeType, download_runtime, download_runtime_for_project, is_valid_version,
@@ -187,10 +188,8 @@ impl JsExecutor {
187188
config::read_session_version().await
188189
};
189190
if let Some(version) = session_version {
191+
self.check_runtime_compatibility(&version).await?;
190192
let runtime = download_runtime(JsRuntimeType::Node, &version).await?;
191-
if let Some(req) = self.get_cli_engines_requirement().await {
192-
check_runtime_compatibility(&runtime, &req)?;
193-
}
194193
return Ok(self.project_runtime.insert(runtime));
195194
}
196195

@@ -205,20 +204,54 @@ impl JsExecutor {
205204
// At least one valid project source exists — delegate to
206205
// download_runtime_for_project for cache-aware range resolution
207206
// and intra-project fallback chain
208-
download_runtime_for_project(project_path).await?
207+
let runtime = download_runtime_for_project(project_path).await?;
208+
self.check_runtime_compatibility(&runtime.version).await?;
209+
runtime
209210
} else {
210211
// No valid project source — check user default from config, then LTS
211212
let resolution = config::resolve_version(project_path).await?;
213+
self.check_runtime_compatibility(&resolution.version).await?;
212214
download_runtime(JsRuntimeType::Node, &resolution.version).await?
213215
};
214-
if let Some(req) = self.get_cli_engines_requirement().await {
215-
check_runtime_compatibility(&runtime, &req)?;
216-
}
217216
self.project_runtime = Some(runtime);
218217
}
219218
Ok(self.project_runtime.as_ref().unwrap())
220219
}
221220

221+
/// Check that a resolved runtime's version satisfies vp's engine requirements.
222+
///
223+
/// Skips silently when:
224+
/// - The runtime is a system install (version == `"system"`)
225+
/// - The version or requirement strings cannot be parsed as semver
226+
///
227+
/// Returns [`Error::NodeVersionIncompatible`] when the version is parseable but
228+
/// outside the required range.
229+
async fn check_runtime_compatibility(&self, version: &str) -> Result<(), Error> {
230+
let Some(requirement) = self.get_cli_engines_requirement().await else { return Ok(()) };
231+
232+
// System runtimes report "system" — we cannot inspect the actual version cheaply,
233+
// and the user has explicitly opted in via `vp env off`.
234+
if version == "system" {
235+
return Ok(());
236+
}
237+
238+
let normalized = version.strip_prefix('v').unwrap_or(version);
239+
let Ok(version) = Version::parse(normalized) else {
240+
return Ok(()); // unparsable version — skip silently
241+
};
242+
let Ok(range) = Range::parse(&requirement) else {
243+
return Ok(()); // invalid range in package.json — skip silently
244+
};
245+
246+
if !range.satisfies(&version) {
247+
return Err(Error::NodeVersionIncompatible {
248+
version: version.to_string(),
249+
requirement: requirement.to_string(),
250+
});
251+
}
252+
Ok(())
253+
}
254+
222255
/// Download a specific Node.js version.
223256
///
224257
/// This is used when we need a specific version regardless of
@@ -422,42 +455,6 @@ async fn has_valid_version_source(
422455
Ok(engines_valid || dev_engines_valid)
423456
}
424457

425-
/// Check that a resolved runtime's version satisfies vp's engine requirements.
426-
///
427-
/// Skips silently when:
428-
/// - The runtime is a system install (version == `"system"`)
429-
/// - The version or requirement strings cannot be parsed as semver
430-
///
431-
/// Returns [`Error::NodeVersionIncompatible`] when the version is parseable but
432-
/// outside the required range.
433-
fn check_runtime_compatibility(runtime: &JsRuntime, requirement: &str) -> Result<(), Error> {
434-
use node_semver::{Range, Version};
435-
436-
let version_str = runtime.version();
437-
438-
// System runtimes report "system" — we cannot inspect the actual version cheaply,
439-
// and the user has explicitly opted in via `vp env off`.
440-
if version_str == "system" {
441-
return Ok(());
442-
}
443-
444-
let normalized = version_str.strip_prefix('v').unwrap_or(version_str);
445-
let Ok(version) = Version::parse(normalized) else {
446-
return Ok(()); // unparsable version — skip silently
447-
};
448-
let Ok(range) = Range::parse(requirement) else {
449-
return Ok(()); // invalid range in package.json — skip silently
450-
};
451-
452-
if !range.satisfies(&version) {
453-
return Err(Error::NodeVersionIncompatible {
454-
version: version_str.to_string(),
455-
requirement: requirement.to_string(),
456-
});
457-
}
458-
Ok(())
459-
}
460-
461458
/// Try to find system Node.js when in system-first mode (`vp env off`).
462459
///
463460
/// Returns `Some(JsRuntime)` when both conditions are met:

0 commit comments

Comments
 (0)