Skip to content

Commit 88b7372

Browse files
committed
fix: prefer index over current file for . and ./
1 parent f2809b0 commit 88b7372

File tree

4 files changed

+23
-3
lines changed

4 files changed

+23
-3
lines changed

fixtures/dot/dot.js

Whitespace-only changes.

fixtures/dot/index.js

Whitespace-only changes.

src/lib.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ impl<C: Cache<Cp = FsCachedPath>> ResolverGeneric<C> {
341341
Some(Component::RootDir | Component::Prefix(_)) => {
342342
self.require_absolute(cached_path, specifier, ctx)
343343
}
344-
// 3. If X begins with './' or '/' or '../'
344+
// 3. If X is '.' or begins with './' or '/' or '../'
345345
Some(Component::CurDir | Component::ParentDir) => {
346346
self.require_relative(cached_path, specifier, ctx)
347347
}
@@ -420,7 +420,7 @@ impl<C: Cache<Cp = FsCachedPath>> ResolverGeneric<C> {
420420
Err(ResolveError::NotFound(specifier.to_string()))
421421
}
422422

423-
// 3. If X begins with './' or '/' or '../'
423+
// 3. If X is '.' or begins with './' or '/' or '../'
424424
fn require_relative(
425425
&self,
426426
cached_path: &C::Cp,
@@ -622,7 +622,12 @@ impl<C: Cache<Cp = FsCachedPath>> ResolverGeneric<C> {
622622
if self.options.resolve_to_context {
623623
return Ok(self.cache.is_dir(cached_path, ctx).then(|| cached_path.clone()));
624624
}
625-
if !specifier.ends_with('/') {
625+
let is_dot_slash = specifier == "./";
626+
if is_dot_slash || !specifier.ends_with('/') {
627+
if is_dot_slash || specifier == "." {
628+
let cached_path = &cached_path.normalize_with("../index.js", self.cache.as_ref());
629+
return self.load_alias_or_file(cached_path, ctx);
630+
}
626631
if let Some(path) = self.load_as_file(cached_path, ctx)? {
627632
return Ok(Some(path));
628633
}

src/tests/resolve.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,21 @@ fn prefer_file_over_dir() {
132132
}
133133
}
134134

135+
#[test]
136+
fn resolve_dot() {
137+
let f = super::fixture_root().join("dot");
138+
let dot = f.join("dot.js");
139+
let resolver = Resolver::default();
140+
let data = [
141+
("dot", dot.clone(), ".", f.join("index.js")),
142+
("dot slash", dot, "./", f.join("index.js")),
143+
];
144+
for (comment, path, request, expected) in data {
145+
let resolved_path = resolver.resolve(&path, request).map(|r| r.full_path());
146+
assert_eq!(resolved_path, Ok(expected), "{comment} {path:?} {request}");
147+
}
148+
}
149+
135150
#[cfg(windows)]
136151
#[test]
137152
fn resolve_normalized_on_windows() {

0 commit comments

Comments
 (0)