Repository: oxc-project/oxc-resolver
Pull request #144 (2024-04-24 04:40:29)

fix: RootsPlugin should fall through if it fails to resolve the roots
Prefix for https://github.com/web-infra-dev/rspack/pull/6340

In enhanced-resolve, when resolving with `roots` failed, will continue resolve it instead of returning error

codspeed-hq[bot]: ## [CodSpeed Performance Report](https://codspeed.io/oxc-project/oxc-resolver/branches/ahabhgk:fix-roots-fall-through)

### Merging #144 will **not alter performance**

<sub>Comparing <code>ahabhgk:fix-roots-fall-through</code> (044b642) with <code>main</code> (d345d3d)</sub>



### Summary

`✅ 2` untouched benchmarks






Patch:
diff --git a/fixtures/enhanced_resolve/test/fixtures/roots_fall_through/index.js b/fixtures/enhanced_resolve/test/fixtures/roots_fall_through/index.js
new file mode 100644
index 0000000..e69de29
diff --git a/src/lib.rs b/src/lib.rs
index 57cc967..b45caeb 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -333,27 +333,21 @@ impl<Fs: FileSystem> ResolverGeneric<Fs> {
                 return Ok(path);
             }
         }
-        if self.options.roots.is_empty() {
-            // 2. If X begins with '/'
-            //   a. set Y to be the file system root
-            let path = self.cache.value(Path::new(specifier));
-            if let Some(path) = self.load_as_file_or_directory(&path, specifier, ctx)? {
+        // enhanced-resolve: RootsPlugin
+        for root in &self.options.roots {
+            let cached_path = self.cache.value(root);
+            let specifier = specifier.trim_start_matches(SLASH_START);
+            if let Ok(path) = self.require_relative(&cached_path, specifier, ctx) {
                 return Ok(path);
             }
-            Err(ResolveError::NotFound(specifier.to_string()))
-        } else {
-            for root in &self.options.roots {
-                let cached_path = self.cache.value(root);
-                if let Ok(path) = self.require_relative(
-                    &cached_path,
-                    specifier.trim_start_matches(SLASH_START),
-                    ctx,
-                ) {
-                    return Ok(path);
-                }
-            }
-            Err(ResolveError::NotFound(specifier.to_string()))
         }
+        // 2. If X begins with '/'
+        //   a. set Y to be the file system root
+        let path = self.cache.value(Path::new(specifier));
+        if let Some(path) = self.load_as_file_or_directory(&path, specifier, ctx)? {
+            return Ok(path);
+        }
+        Err(ResolveError::NotFound(specifier.to_string()))
     }
 
     // 3. If X begins with './' or '/' or '../'


Test patch:
diff --git a/src/tests/roots.rs b/src/tests/roots.rs
index 72f122f..cc3b489 100644
--- a/src/tests/roots.rs
+++ b/src/tests/roots.rs
@@ -78,3 +78,12 @@ fn prefer_absolute() {
         assert_eq!(resolved_path, Ok(expected), "{comment} {request}");
     }
 }
+
+#[test]
+fn roots_fall_through() {
+    let f = super::fixture();
+    let absolute_path = f.join("roots_fall_through/index.js");
+    let specifier = absolute_path.to_string_lossy();
+    let resolution = Resolver::new(ResolveOptions::default().with_root(&f)).resolve(&f, &specifier);
+    assert_eq!(resolution.map(|r| r.into_path_buf()), Ok(absolute_path));
+}