Skip to content

Commit c410374

Browse files
authored
fix: handle query and fragment in pacakge.json exports and imports field (#443)
package.json `exports` and `imports` field con contain queries or fragments: `"exports": { ".": { "default": "./foo.js?query#fragment" }` closes #417
1 parent ffbdfa5 commit c410374

File tree

5 files changed

+16
-2
lines changed

5 files changed

+16
-2
lines changed

fixtures/enhanced_resolve/test/fixtures/exports-field/node_modules/exports-field/package.json

Lines changed: 3 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

fixtures/enhanced_resolve/test/fixtures/imports-field/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
"#b": "../b.js",
88
"#ccc/": "c/",
99
"#c": "c",
10-
"#a/": "a/"
10+
"#a/": "a/",
11+
"#query": "./a.js?query",
12+
"#fragment": "./a.js#fragment"
1113
},
1214
"other": {
1315
"imports": {

src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1634,6 +1634,12 @@ impl<C: Cache> ResolverGeneric<C> {
16341634

16351635
// 1. If target is a String, then
16361636
if let Some(target) = target.as_string() {
1637+
// Target string con contain queries or fragments:
1638+
// `"exports": { ".": { "default": "./foo.js?query#fragment" }`
1639+
let parsed = Specifier::parse(target).map_err(ResolveError::Specifier)?;
1640+
ctx.with_query_fragment(parsed.query, parsed.fragment);
1641+
let target = parsed.path();
1642+
16371643
// 1. If target does not start with "./", then
16381644
if !target.starts_with("./") {
16391645
// 1. If isImports is false, or if target starts with "../" or "/", or if target is a valid URL, then

src/tests/exports_field.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ fn test_simple() {
2929
let pass = [
3030
("resolve root using exports field, not a main field", f.clone(), "exports-field", f.join("node_modules/exports-field/x.js")),
3131
("resolver should respect condition names", f.clone(), "exports-field/dist/main.js", f.join("node_modules/exports-field/lib/lib2/main.js")),
32+
("should resolve query", f.clone(), "exports-field/query.js", f.join("node_modules/exports-field/x.js?query")),
33+
("should resolve fragment", f.clone(), "exports-field/fragment.js", f.join("node_modules/exports-field/x.js#fragment")),
3234
// enhanced_resolve behaves differently to node.js. enhanced_resolve fallbacks when an
3335
// array item is unresolved, where as node.js fallbacks when an array has an
3436
// InvalidPackageTarget error.

src/tests/imports_field.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ fn test_simple() {
2626
#[rustfmt::skip]
2727
let pass = [
2828
("should resolve using imports field instead of self-referencing", f.clone(), "#imports-field", f.join("b.js")),
29+
("should resolve query", f.clone(), "#query", f.join("a.js?query")),
30+
("should resolve fragment", f.clone(), "#fragment", f.join("a.js#fragment")),
2931
("should resolve using imports field instead of self-referencing for a subpath", f.join("dir"), "#imports-field", f.join("b.js")),
3032
("should resolve package #1", f.clone(), "#a/dist/main.js", f.join("node_modules/a/lib/lib2/main.js")),
3133
("should resolve package #3", f.clone(), "#ccc/index.js", f.join("node_modules/c/index.js")),

0 commit comments

Comments
 (0)