Skip to content

Commit 75b9e76

Browse files
authored
Merge pull request #17116 from webpack/fix-hash-in-url
fix: handle `#hash` URL as external
2 parents 4fb73da + 641db80 commit 75b9e76

20 files changed

Lines changed: 134 additions & 54 deletions

lib/WebpackOptionsApply.js

Lines changed: 33 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -119,47 +119,40 @@ class WebpackOptionsApply extends OptionsApply {
119119
if (options.externalsPresets.webAsync) {
120120
//@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
121121
const ExternalsPlugin = require("./ExternalsPlugin");
122-
new ExternalsPlugin(
123-
"import",
124-
options.experiments.css
125-
? ({ request, dependencyType }, callback) => {
126-
if (dependencyType === "url") {
127-
if (/^(\/\/|https?:\/\/)/.test(request))
128-
return callback(null, `asset ${request}`);
129-
} else if (dependencyType === "css-import") {
130-
if (/^(\/\/|https?:\/\/)/.test(request))
131-
return callback(null, `css-import ${request}`);
132-
} else if (/^(\/\/|https?:\/\/|std:)/.test(request)) {
133-
if (/^\.css(\?|$)/.test(request))
134-
return callback(null, `css-import ${request}`);
135-
return callback(null, `import ${request}`);
136-
}
137-
callback();
138-
}
139-
: /^(\/\/|https?:\/\/|std:)/
140-
).apply(compiler);
122+
new ExternalsPlugin("import", ({ request, dependencyType }, callback) => {
123+
if (dependencyType === "url") {
124+
if (/^(\/\/|https?:\/\/|#)/.test(request))
125+
return callback(null, `asset ${request}`);
126+
} else if (options.experiments.css && dependencyType === "css-import") {
127+
if (/^(\/\/|https?:\/\/|#)/.test(request))
128+
return callback(null, `css-import ${request}`);
129+
} else if (
130+
options.experiments.css &&
131+
/^(\/\/|https?:\/\/|std:)/.test(request)
132+
) {
133+
if (/^\.css(\?|$)/.test(request))
134+
return callback(null, `css-import ${request}`);
135+
return callback(null, `import ${request}`);
136+
}
137+
callback();
138+
}).apply(compiler);
141139
} else if (options.externalsPresets.web) {
142140
//@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
143141
const ExternalsPlugin = require("./ExternalsPlugin");
144-
new ExternalsPlugin(
145-
"module",
146-
options.experiments.css
147-
? ({ request, dependencyType }, callback) => {
148-
if (dependencyType === "url") {
149-
if (/^(\/\/|https?:\/\/)/.test(request))
150-
return callback(null, `asset ${request}`);
151-
} else if (dependencyType === "css-import") {
152-
if (/^(\/\/|https?:\/\/)/.test(request))
153-
return callback(null, `css-import ${request}`);
154-
} else if (/^(\/\/|https?:\/\/|std:)/.test(request)) {
155-
if (/^\.css(\?|$)/.test(request))
156-
return callback(null, `css-import ${request}`);
157-
return callback(null, `module ${request}`);
158-
}
159-
callback();
160-
}
161-
: /^(\/\/|https?:\/\/|std:)/
162-
).apply(compiler);
142+
new ExternalsPlugin("module", ({ request, dependencyType }, callback) => {
143+
if (dependencyType === "url") {
144+
if (/^(\/\/|https?:\/\/|#)/.test(request))
145+
return callback(null, `asset ${request}`);
146+
} else if (options.experiments.css && dependencyType === "css-import") {
147+
if (/^(\/\/|https?:\/\/|#)/.test(request))
148+
return callback(null, `css-import ${request}`);
149+
} else if (/^(\/\/|https?:\/\/|std:)/.test(request)) {
150+
if (options.experiments.css && /^\.css((\?)|$)/.test(request))
151+
return callback(null, `css-import ${request}`);
152+
return callback(null, `module ${request}`);
153+
}
154+
callback();
155+
}).apply(compiler);
163156
} else if (options.externalsPresets.node) {
164157
if (options.experiments.css) {
165158
//@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
@@ -168,10 +161,10 @@ class WebpackOptionsApply extends OptionsApply {
168161
"module",
169162
({ request, dependencyType }, callback) => {
170163
if (dependencyType === "url") {
171-
if (/^(\/\/|https?:\/\/)/.test(request))
164+
if (/^(\/\/|https?:\/\/|#)/.test(request))
172165
return callback(null, `asset ${request}`);
173166
} else if (dependencyType === "css-import") {
174-
if (/^(\/\/|https?:\/\/)/.test(request))
167+
if (/^(\/\/|https?:\/\/|#)/.test(request))
175168
return callback(null, `css-import ${request}`);
176169
} else if (/^(\/\/|https?:\/\/|std:)/.test(request)) {
177170
if (/^\.css(\?|$)/.test(request))

lib/css/CssParser.js

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -380,12 +380,8 @@ class CssParser extends Parser {
380380
break;
381381
}
382382
default: {
383-
if (
384-
// Ignore `url(#highlight)` URLs
385-
/^#/.test(value) ||
386-
// Ignore `url()`, `url('')` and `url("")`, they are valid by spec
387-
value.length === 0
388-
) {
383+
// Ignore `url()`, `url('')` and `url("")`, they are valid by spec
384+
if (value.length === 0) {
389385
break;
390386
}
391387

@@ -429,12 +425,8 @@ class CssParser extends Parser {
429425
) {
430426
let value = normalizeUrl(input.slice(start + 1, end - 1), true);
431427

432-
if (
433-
// Ignore `url(#highlight)` URLs
434-
/^#/.test(value) ||
435-
// Ignore `url()`, `url('')` and `url("")`, they are valid by spec
436-
value.length === 0
437-
) {
428+
// Ignore `url()`, `url('')` and `url("")`, they are valid by spec
429+
if (value.length === 0) {
438430
break;
439431
}
440432

test/__snapshots__/ConfigCacheTestCases.longtest.js.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -765,7 +765,7 @@ Object {
765765
"a187": " image-set(url(img.09a1a1112c577c279435.png)1x,url(img.09a1a1112c577c279435.png)2x,url(img.09a1a1112c577c279435.png)3x)",
766766
"a188": " image-set(url(img.09a1a1112c577c279435.png)1x,url(img.09a1a1112c577c279435.png)2x,url(img.09a1a1112c577c279435.png)3x)",
767767
"a189": " image-set(url(img.09a1a1112c577c279435.png)1x,url(img.09a1a1112c577c279435.png)2x,url(img.09a1a1112c577c279435.png)3x)",
768-
"a19": " url('#line-marker')",
768+
"a19": " url(#line-marker)",
769769
"a190": " image-set(url(img.09a1a1112c577c279435.png)1x)",
770770
"a191": " image-set(url(img.09a1a1112c577c279435.png)1x/* test*/,/* test*/url(img.09a1a1112c577c279435.png)2x)",
771771
"a197": " \\\\u\\\\r\\\\l(img.09a1a1112c577c279435.png)",

test/__snapshots__/ConfigTestCases.basictest.js.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -765,7 +765,7 @@ Object {
765765
"a187": " image-set(url(img.09a1a1112c577c279435.png)1x,url(img.09a1a1112c577c279435.png)2x,url(img.09a1a1112c577c279435.png)3x)",
766766
"a188": " image-set(url(img.09a1a1112c577c279435.png)1x,url(img.09a1a1112c577c279435.png)2x,url(img.09a1a1112c577c279435.png)3x)",
767767
"a189": " image-set(url(img.09a1a1112c577c279435.png)1x,url(img.09a1a1112c577c279435.png)2x,url(img.09a1a1112c577c279435.png)3x)",
768-
"a19": " url('#line-marker')",
768+
"a19": " url(#line-marker)",
769769
"a190": " image-set(url(img.09a1a1112c577c279435.png)1x)",
770770
"a191": " image-set(url(img.09a1a1112c577c279435.png)1x/* test*/,/* test*/url(img.09a1a1112c577c279435.png)2x)",
771771
"a197": " \\\\u\\\\r\\\\l(img.09a1a1112c577c279435.png)",
14.6 KB
Loading
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import img from "#internal";
2+
3+
it("should allow to use an URL started with '#'", () => {
4+
const url = new URL("#test", import.meta.url);
5+
expect(url.hash).toBe("#test");
6+
});
7+
8+
it("should allow to use an URL started with '#'", () => {
9+
expect(img).toEndWith("path/images/file.png");
10+
});
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"name": "pkg",
3+
"exports": "./pkg.mjs",
4+
"imports": {
5+
"#internal": "./file.png"
6+
}
7+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/** @type {import("../../../../").Configuration} */
2+
module.exports = {
3+
mode: "development",
4+
output: {
5+
assetModuleFilename: "images/file[ext]"
6+
},
7+
module: {
8+
rules: [
9+
{
10+
test: /\.png$/,
11+
type: "asset/resource"
12+
}
13+
]
14+
},
15+
target: "web"
16+
};

test/configCases/css/basic-initial-only/style.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
@import url(https://test.cases/path/../../../../configCases/css/css-import/external.css);
12
@import "style-imported.css";
23
body {
34
background: red;

test/configCases/css/basic-initial-only/webpack.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
module.exports = {
33
target: "web",
44
mode: "development",
5+
externalsPresets: { web: false, webAsync: true },
56
experiments: {
67
css: true
78
}

0 commit comments

Comments
 (0)