From 9b5a74cab08585e344e4a4981e4206404d955dbb Mon Sep 17 00:00:00 2001 From: Rob Hannay Date: Fri, 16 Jan 2026 09:31:37 +0000 Subject: [PATCH] feat: add clear_cache_without_tsconfig for HMR optimization Add a new method `clear_cache_without_tsconfig()` that clears the path cache while preserving the tsconfig cache. This is useful for HMR (Hot Module Replacement) scenarios where tsconfig.json doesn't change during development. When using tsconfig path aliases (especially wildcard patterns like `"*": ["./src/*"]`), HMR can intermittently fail with "Module not found" errors because: 1. During HMR, rspack calls `clear_cache()` which clears both the path cache AND tsconfig cache 2. Re-parsing `tsconfig.json` on every HMR update is wasteful 3. Race conditions during re-parsing can cause intermittent module resolution failures Related: https://github.com/web-infra-dev/rspack/issues/12753 Co-Authored-By: Claude Opus 4.5 --- src/cache.rs | 8 ++++++++ src/lib.rs | 15 +++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/src/cache.rs b/src/cache.rs index 8d54f36..6ca0229 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -42,6 +42,14 @@ impl Cache { self.tsconfigs.clear(); } + /// Clear the path cache without clearing the tsconfig cache. + /// + /// This is useful for HMR (Hot Module Replacement) scenarios where tsconfig.json + /// doesn't change during development, but file system state may change. + pub fn clear_without_tsconfig(&self) { + self.paths.clear(); + } + pub fn value(&self, path: &Path) -> CachedPath { let hash = { let mut hasher = FxHasher::default(); diff --git a/src/lib.rs b/src/lib.rs index e42a24d..6fcb16e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -185,6 +185,21 @@ impl ResolverGeneric { } } + /// Clear the underlying cache without clearing tsconfig cache. + /// + /// This is useful for HMR (Hot Module Replacement) scenarios where tsconfig.json + /// doesn't change during development, but file system state may change. + /// Preserving the tsconfig cache avoids re-parsing tsconfig.json on every HMR update, + /// which can cause intermittent module resolution failures with tsconfig path aliases. + pub fn clear_cache_without_tsconfig(&self) { + self.cache.clear_without_tsconfig(); + #[cfg(feature = "yarn_pnp")] + { + self.pnp_manifest_content_cache.clear(); + self.pnp_manifest_path_cache.clear(); + } + } + /// Resolve `specifier` at an absolute path to a `directory`. /// /// A specifier is the string passed to require or import, i.e. `require("specifier")` or `import "specifier"`.