From c1cbaa2d42ac937105951800617b40d59a43cdf8 Mon Sep 17 00:00:00 2001 From: Boshen Date: Wed, 26 Nov 2025 05:25:40 +0000 Subject: [PATCH] perf: remove the redundant `node_modules/package/index` cache value (#875) closes #851 --- src/cache/cached_path.rs | 17 ++++++++++++ src/lib.rs | 57 ++++++++++++++-------------------------- 2 files changed, 36 insertions(+), 38 deletions(-) diff --git a/src/cache/cached_path.rs b/src/cache/cached_path.rs index 79f2ccd6..81c4d1e3 100644 --- a/src/cache/cached_path.rs +++ b/src/cache/cached_path.rs @@ -120,6 +120,23 @@ impl CachedPath { }) } + pub(crate) fn add_name_and_extension( + &self, + name: &str, + ext: &str, + cache: &Cache, + ) -> Self { + SCRATCH_PATH.with_borrow_mut(|path| { + path.clear(); + let s = path.as_mut_os_string(); + s.push(self.path.as_os_str()); + s.push(std::path::MAIN_SEPARATOR_STR); + s.push(name); + s.push(ext); + cache.value(path) + }) + } + pub(crate) fn replace_extension(&self, ext: &str, cache: &Cache) -> Self { SCRATCH_PATH.with_borrow_mut(|path| { path.clear(); diff --git a/src/lib.rs b/src/lib.rs index 4fafbff1..888e3a23 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -656,10 +656,13 @@ impl ResolverGeneric { // 2. If X.js is a file, load X.js as JavaScript text. STOP // 3. If X.json is a file, parse X.json to a JavaScript Object. STOP // 4. If X.node is a file, load X.node as binary addon. STOP - if let Some(path) = - self.load_extensions(cached_path, &self.options.extensions, tsconfig, ctx)? - { - return Ok(Some(path)); + if !ctx.fully_specified { + for extension in &self.options.extensions { + let cached_path = cached_path.add_extension(extension, self.cache.as_ref()); + if let Some(path) = self.load_alias_or_file(&cached_path, tsconfig, ctx)? { + return Ok(Some(path)); + } + } } Ok(None) } @@ -740,25 +743,6 @@ impl ResolverGeneric { Ok(None) } - fn load_extensions( - &self, - path: &CachedPath, - extensions: &[String], - tsconfig: Option<&TsConfig>, - ctx: &mut Ctx, - ) -> ResolveResult { - if ctx.fully_specified { - return Ok(None); - } - for extension in extensions { - let cached_path = path.add_extension(extension, self.cache.as_ref()); - if let Some(path) = self.load_alias_or_file(&cached_path, tsconfig, ctx)? { - return Ok(Some(path)); - } - } - Ok(None) - } - fn load_realpath(&self, cached_path: &CachedPath) -> Result { if self.options.symlinks { self.cache.canonicalize(cached_path) @@ -801,21 +785,18 @@ impl ResolverGeneric { tsconfig: Option<&TsConfig>, ctx: &mut Ctx, ) -> ResolveResult { - for main_file in &self.options.main_files { - let cached_path = cached_path.normalize_with(main_file, self.cache.as_ref()); - if self.options.enforce_extension.is_disabled() - && let Some(path) = self.load_browser_field_or_alias(&cached_path, tsconfig, ctx)? - && self.check_restrictions(path.path()) - { - return Ok(Some(path)); - } - // 1. If X/index.js is a file, load X/index.js as JavaScript text. STOP - // 2. If X/index.json is a file, parse X/index.json to a JavaScript object. STOP - // 3. If X/index.node is a file, load X/index.node as binary addon. STOP - if let Some(path) = - self.load_extensions(&cached_path, &self.options.extensions, tsconfig, ctx)? - { - return Ok(Some(path)); + if !ctx.fully_specified { + for main_file in &self.options.main_files { + // 1. If X/index.js is a file, load X/index.js as JavaScript text. STOP + // 2. If X/index.json is a file, parse X/index.json to a JavaScript object. STOP + // 3. If X/index.node is a file, load X/index.node as binary addon. STOP + for extension in &self.options.extensions { + let cached_path = + cached_path.add_name_and_extension(main_file, extension, &self.cache); + if let Some(path) = self.load_alias_or_file(&cached_path, tsconfig, ctx)? { + return Ok(Some(path)); + } + } } } Ok(None)