Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file.
Empty file.
3 changes: 3 additions & 0 deletions fixtures/prefer-file-over-dir/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "prefer-file-over-dir"
}
3 changes: 0 additions & 3 deletions fixtures/prefer-file-over-pkg/package.json

This file was deleted.

24 changes: 14 additions & 10 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -781,13 +781,6 @@ impl<C: Cache<Cp = FsCachedPath>> ResolverGeneric<C> {
// may have a @scope/ prefix and the subpath begins with a slash (`/`).
if !package_name.is_empty() {
let cached_path = cached_path.normalize_with(package_name, self.cache.as_ref());
// file is preferred over directory when specifier doesn't contains a slash which indicates a dir
// node_modules/bar.js vs node_modules/bar/index.js
if !specifier.contains('/') {
if let Some(path) = self.load_as_file(&cached_path, ctx)? {
return Ok(Some(path));
}
}
// Try foo/node_modules/package_name
if self.cache.is_dir(&cached_path, ctx) {
// a. LOAD_PACKAGE_EXPORTS(X, DIR)
Expand Down Expand Up @@ -823,6 +816,19 @@ impl<C: Cache<Cp = FsCachedPath>> ResolverGeneric<C> {
if self.options.resolve_to_context {
return Ok(self.cache.is_dir(&cached_path, ctx).then(|| cached_path.clone()));
}

if self.options.alias_fields.is_empty() && self.cache.is_file(&cached_path, ctx) {
return Ok(Some(cached_path));
}

// `is_file` could be false because no extensions are considered yet,
// so we need to try `load_as_file` first when `specifier` does not end with a slash which indicates a dir instead.
if !specifier.ends_with('/') {
if let Some(path) = self.load_as_file(&cached_path, ctx)? {
return Ok(Some(path));
}
}

if self.cache.is_dir(&cached_path, ctx) {
if let Some(path) = self.load_browser_field_or_alias(&cached_path, ctx)? {
return Ok(Some(path));
Expand All @@ -831,9 +837,7 @@ impl<C: Cache<Cp = FsCachedPath>> ResolverGeneric<C> {
return Ok(Some(path));
}
}
if let Some(path) = self.load_as_file(&cached_path, ctx)? {
return Ok(Some(path));
}

if let Some(path) = self.load_as_directory(&cached_path, ctx)? {
return Ok(Some(path));
}
Expand Down
15 changes: 10 additions & 5 deletions src/tests/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,12 +119,17 @@ fn resolve_hash_as_module() {
}

#[test]
fn prefer_file_over_pkg() {
let f = super::fixture_root();
let fixture = f.join("prefer-file-over-pkg");
fn prefer_file_over_dir() {
let f = super::fixture_root().join("prefer-file-over-dir");
let resolver = Resolver::default();
let resolved_path = resolver.resolve(fixture.clone(), "bar").map(|r| r.full_path());
assert_eq!(resolved_path, Ok(fixture.join("node_modules/bar.js")));
let data = [
("one level package name", f.clone(), "bar", f.join("node_modules/bar.js")),
("scoped level package name", f.clone(), "@foo/bar", f.join("node_modules/@foo/bar.js")),
];
for (comment, path, request, expected) in data {
let resolved_path = resolver.resolve(&path, request).map(|r| r.full_path());
assert_eq!(resolved_path, Ok(expected), "{comment} {path:?} {request}");
}
}

#[cfg(windows)]
Expand Down
Loading