Skip to content

Commit d3f52a2

Browse files
authored
fix: resolve symlink with nested node_modules (#125)
1 parent 68b35f5 commit d3f52a2

File tree

10 files changed

+38
-9
lines changed

10 files changed

+38
-9
lines changed

examples/resolver.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ fn main() {
88
let path = PathBuf::from(env::args().nth(1).expect("path"));
99

1010
assert!(path.is_dir(), "{path:?} must be a directory that will be resolved against.");
11-
assert!(path.is_absolute(), "{path:?} must be an absolute path.",);
11+
assert!(path.is_absolute(), "{path:?} must be an absolute path.");
1212

1313
let specifier = env::args().nth(2).expect("specifier");
1414

fixtures/symlink-with-nested-node_modules/.gitignore

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

fixtures/symlink-with-nested-node_modules/bar/node_modules/foo

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

fixtures/symlink-with-nested-node_modules/foo/node_modules/dep/index.js

Whitespace-only changes.

fixtures/symlink-with-nested-node_modules/foo/node_modules/foo/index.js

Whitespace-only changes.

src/lib.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -278,9 +278,22 @@ impl<C: Cache<Cp = FsCachedPath>> ResolverGeneric<C> {
278278
ctx: &mut Ctx,
279279
) -> Result<Resolution<C>, ResolveError> {
280280
ctx.with_fully_specified(self.options.fully_specified);
281-
let cached_path = self.cache.value(path);
281+
282+
let cached_path = if self.options.symlinks {
283+
self.load_realpath(&self.cache.value(path))?
284+
} else {
285+
path.to_path_buf()
286+
};
287+
288+
let cached_path = self.cache.value(&cached_path);
282289
let cached_path = self.require(&cached_path, specifier, ctx)?;
283-
let path = self.load_realpath(&cached_path)?;
290+
291+
let path = if self.options.symlinks {
292+
self.load_realpath(&cached_path)?
293+
} else {
294+
cached_path.to_path_buf()
295+
};
296+
284297
// enhanced-resolve: restrictions
285298
self.check_restrictions(&path)?;
286299
let package_json =

src/tests/alias.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ fn all_alias_values_are_not_found() {
254254
let resolution = resolver.resolve(&f, "m1/a.js");
255255
assert_eq!(
256256
resolution,
257-
Err(ResolveError::MatchedAliasNotFound("m1/a.js".to_string(), "m1".to_string(),))
257+
Err(ResolveError::MatchedAliasNotFound("m1/a.js".to_string(), "m1".to_string()))
258258
);
259259
}
260260

src/tests/resolve.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ fn issue238_resolve() {
6868
});
6969
let resolved_path =
7070
resolver.resolve(f.join("src/common"), "config/myObjectFile").map(|r| r.full_path());
71-
assert_eq!(resolved_path, Ok(f.join("src/common/config/myObjectFile.js")),);
71+
assert_eq!(resolved_path, Ok(f.join("src/common/config/myObjectFile.js")));
7272
}
7373

7474
#[test]
@@ -151,6 +151,22 @@ fn resolve_dot() {
151151
}
152152
}
153153

154+
#[test]
155+
fn symlink_with_nested_node_modules() {
156+
let f = super::fixture_root().join("symlink-with-nested-node_modules");
157+
158+
let resolver = Resolver::default();
159+
let resolved_path =
160+
resolver.resolve(f.join("bar/node_modules/foo"), "dep").map(|r| r.full_path());
161+
assert_eq!(resolved_path, Ok(f.join("foo/node_modules/dep/index.js")));
162+
163+
let resolver = Resolver::new(ResolveOptions { symlinks: false, ..ResolveOptions::default() });
164+
assert_eq!(
165+
resolver.resolve(f.join("bar/node_modules/foo"), "dep"),
166+
Err(ResolveError::NotFound("dep".into()))
167+
);
168+
}
169+
154170
#[cfg(windows)]
155171
#[test]
156172
fn resolve_normalized_on_windows() {

src/tests/symlink.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -196,9 +196,6 @@ fn test_unsupported_targets() {
196196
let dos_device_temp_path = get_dos_device_path(&temp_path).unwrap();
197197
assert_eq!(
198198
resolver_with_symlinks.resolve(&dos_device_temp_path, "./index.js"),
199-
// There is `package.json` under fixtures/enhanced_resolve, so in practice the Error will be thrown there.
200-
Err(ResolveError::PathNotSupported(
201-
dos_device_temp_path.parent().unwrap().parent().unwrap().to_path_buf()
202-
))
199+
Err(ResolveError::PathNotSupported(dos_device_temp_path))
203200
);
204201
}

tests/resolve_test.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ fn postcss() {
9696
let module_path = path.join("node_modules/postcss");
9797
let resolver = Resolver::new(ResolveOptions {
9898
alias_fields: vec![vec!["browser".into()]],
99+
symlinks: false,
99100
..ResolveOptions::default()
100101
});
101102

0 commit comments

Comments
 (0)