Skip to content
This repository was archived by the owner on Dec 17, 2025. It is now read-only.

Commit 10503d6

Browse files
refactor!: added isUrlRequest again, but now it ignores only absolute URLs and #hash requests, data URI and root relative request are handled as requestable due webpack v5 support them
1 parent 46b032d commit 10503d6

File tree

4 files changed

+224
-1
lines changed

4 files changed

+224
-1
lines changed

README.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,17 @@ If the loader options have been passed as loader query string (`loader?some&para
1010

1111
Converts some resource URL to a webpack module request.
1212

13+
> i Before call `urlToRequest` you need call `isUrlRequest` to ensure it is requestable url
14+
1315
```javascript
14-
const request = loaderUtils.urlToRequest(url);
16+
const url = "path/to/module.js";
17+
18+
if (loaderUtils.isUrlRequest(url)) {
19+
// Logic for requestable url
20+
const request = loaderUtils.urlToRequest(url);
21+
} else {
22+
// Logic for not requestable url
23+
}
1524
```
1625

1726
Simple example:

lib/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
"use strict";
22

3+
const isUrlRequest = require("./isUrlRequest");
34
const urlToRequest = require("./urlToRequest");
45
const getHashDigest = require("./getHashDigest");
56
const interpolateName = require("./interpolateName");
67

78
exports.urlToRequest = urlToRequest;
89
exports.getHashDigest = getHashDigest;
910
exports.interpolateName = interpolateName;
11+
exports.isUrlRequest = isUrlRequest;

lib/isUrlRequest.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
"use strict";
2+
3+
const path = require("path");
4+
5+
function isUrlRequest(url) {
6+
// An URL is not an request if
7+
8+
// 1. Allow `data URI`
9+
if (/^data:/i.test(url)) {
10+
return true;
11+
}
12+
13+
// 2. It's an absolute url and it is not `windows` path like `C:\dir\file`
14+
if (/^[a-z][a-z0-9+.-]*:/i.test(url) && !path.win32.isAbsolute(url)) {
15+
return false;
16+
}
17+
18+
// 3. It's a protocol-relative
19+
if (/^\/\//.test(url)) {
20+
return false;
21+
}
22+
23+
// 4. It's some kind of url for a template
24+
if (/^#/.test(url)) {
25+
return false;
26+
}
27+
28+
return true;
29+
}
30+
31+
module.exports = isUrlRequest;

test/isUrlRequest.test.js

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
"use strict";
2+
3+
const loaderUtils = require("../");
4+
5+
function ExpectedError(regex) {
6+
this.regex = regex;
7+
}
8+
ExpectedError.prototype.matches = function (err) {
9+
return this.regex.test(err.message);
10+
};
11+
12+
describe("isUrlRequest()", () => {
13+
[
14+
// without root
15+
[["//google.com"], false, "should be negative for scheme-agnostic urls"],
16+
[["http://google.com"], false, "should be negative for http urls"],
17+
[["HTTP://google.com"], false, "should be negative for http urls"],
18+
[["https://google.com"], false, "should be negative for https urls"],
19+
[["HTTPS://google.com"], false, "should be negative for https urls"],
20+
21+
[["chrome-extension://"], false, "should be negative for nonstandard urls"],
22+
[["moz-extension://"], false, "should be negative for nonstandard urls"],
23+
[
24+
["ms-browser-extension://"],
25+
false,
26+
"should be negative for nonstandard urls",
27+
],
28+
[["custom-extension://"], false, "should be negative for nonstandard urls"],
29+
30+
[["path/to/thing"], true, "should be positive for implicit relative urls"],
31+
[["./img.png"], true, "should be positive for implicit relative urls"],
32+
[["../img.png"], true, "should be positive for implicit relative urls"],
33+
[
34+
["./img.png?foo=bar#hash"],
35+
true,
36+
"should be positive for implicit relative urls",
37+
],
38+
[
39+
["./path/to/thing"],
40+
true,
41+
"should be positive for explicit relative urls",
42+
],
43+
[["~path/to/thing"], true, "should be positive for module urls (with ~)"],
44+
[
45+
["some/other/stuff/and/then~path/to/thing"],
46+
true,
47+
"should be positive for module urls with path prefix",
48+
],
49+
[
50+
["./some/other/stuff/and/then~path/to/thing"],
51+
true,
52+
"should be positive for module urls with relative path prefix",
53+
],
54+
[["C:/thing"], true, "should be positive for linux path with driver"],
55+
[["C:\\thing"], true, "should be positive for windows path with driver"],
56+
[
57+
["directory/things"],
58+
true,
59+
"should be positive for relative path (linux)",
60+
],
61+
[
62+
["directory\\things"],
63+
true,
64+
"should be positive for relative path (windows)",
65+
],
66+
67+
// with root (normal path)
68+
[
69+
["path/to/thing", "root/dir"],
70+
true,
71+
"should be positive with root if implicit relative url",
72+
],
73+
[
74+
["./path/to/thing", "root/dir"],
75+
true,
76+
"should be positive with root if explicit relative url",
77+
],
78+
79+
// with root (boolean) on Windows
80+
[
81+
["C:\\path\\to\\thing"],
82+
true,
83+
"should be positive for Windows absolute paths with drive letter",
84+
],
85+
[
86+
["\\\\?\\UNC\\ComputerName\\path\\to\\thing"],
87+
true,
88+
"should be positive for Windows absolute UNC paths",
89+
],
90+
91+
// with root (module)
92+
[
93+
["/path/to/thing", "~"],
94+
true,
95+
"should be positive for module url if root = ~",
96+
],
97+
98+
// with root (module path)
99+
[
100+
["/path/to/thing", "~module"],
101+
true,
102+
"should be positive for module prefixes when root starts with ~",
103+
],
104+
[
105+
["/path/to/thing", "~module/"],
106+
true,
107+
"should be positive for module prefixes (with trailing slash) when root starts with ~",
108+
],
109+
110+
// error cases
111+
[
112+
["/path/to/thing", 1],
113+
new ExpectedError(/unexpected parameters/i),
114+
"should throw an error on invalid root",
115+
],
116+
117+
// empty url
118+
[[""], true, "should be positive if url is empty"],
119+
120+
// about url
121+
[["about:blank"], false, "should be negative for about:blank"],
122+
123+
// hash
124+
[["#gradient"], false, "should be negative for hash url"],
125+
126+
// url
127+
[["//sindresorhus.com"], false, "should ignore noscheme url"],
128+
[
129+
["//at.alicdn.com/t/font_515771_emcns5054x3whfr.eot"],
130+
false,
131+
"should ignore noscheme url with path",
132+
],
133+
[
134+
["https://example.com/././foo"],
135+
false,
136+
"should ignore absolute url with relative",
137+
],
138+
139+
// non standard protocols
140+
[
141+
["file://sindresorhus.com"],
142+
false,
143+
"should ignore non standard protocols (file)",
144+
],
145+
[
146+
["mailto:[email protected]"],
147+
false,
148+
"should ignore non standard protocols (mailto)",
149+
],
150+
[
151+
["data:text/plain;base64,SGVsbG8sIFdvcmxkIQ%3D%3D"],
152+
true,
153+
"should work with non standard protocols (data)",
154+
],
155+
[
156+
["DATA:text/plain;base64,SGVsbG8sIFdvcmxkIQ%3D%3D"],
157+
true,
158+
"should work with non standard protocols (data)",
159+
],
160+
161+
// root-relative url
162+
[["/"], true, "should work with root-relative url 1"],
163+
[["//"], false, "ignore root-relative url 1"],
164+
].forEach((test) => {
165+
it(test[2], () => {
166+
const expected = test[1];
167+
168+
try {
169+
const request = loaderUtils.isUrlRequest.apply(loaderUtils, test[0]);
170+
171+
expect(request).toBe(expected);
172+
} catch (e) {
173+
if (expected instanceof ExpectedError) {
174+
expect(expected.matches(e)).toBe(true);
175+
} else {
176+
throw new Error("should not have thrown an error: " + e.message);
177+
}
178+
}
179+
});
180+
});
181+
});

0 commit comments

Comments
 (0)