Skip to content

Commit f7df4a8

Browse files
refactor: url and import option (webpack-contrib#1299)
1 parent 7019cb0 commit f7df4a8

9 files changed

+2296
-2208
lines changed

README.md

+24-20
Original file line numberDiff line numberDiff line change
@@ -109,16 +109,16 @@ module.exports = {
109109

110110
| Name | Type | Default | Description |
111111
| :-----------------------------------: | :-------------------------: | :----------------: | :--------------------------------------------------------------------- |
112-
| **[`url`](#url)** | `{Boolean\|Function}` | `true` | Enables/Disables `url`/`image-set` functions handling |
113-
| **[`import`](#import)** | `{Boolean\|Function}` | `true` | Enables/Disables `@import` at-rules handling |
112+
| **[`url`](#url)** | `{Boolean\|Object}` | `true` | Enables/Disables `url`/`image-set` functions handling |
113+
| **[`import`](#import)** | `{Boolean\|Object}` | `true` | Enables/Disables `@import` at-rules handling |
114114
| **[`modules`](#modules)** | `{Boolean\|String\|Object}` | `{auto: true}` | Enables/Disables CSS Modules and their configuration |
115115
| **[`sourceMap`](#sourcemap)** | `{Boolean}` | `compiler.devtool` | Enables/Disables generation of source maps |
116116
| **[`importLoaders`](#importloaders)** | `{Number}` | `0` | Enables/Disables or setups number of loaders applied before CSS loader |
117117
| **[`esModule`](#esmodule)** | `{Boolean}` | `true` | Use ES modules syntax |
118118

119119
### `url`
120120

121-
Type: `Boolean|Function`
121+
Type: `Boolean|Object`
122122
Default: `true`
123123

124124
Enables/Disables handling the CSS functions `url` and `image-set`. If set to `false`, `css-loader` will not parse any paths specified in `url` or `image-set`. A function can also be passed to control this behavior dynamically based on the path to the asset. Starting with version [4.0.0](https://github.com/webpack-contrib/css-loader/blob/master/CHANGELOG.md#400-2020-07-25), absolute paths are parsed based on the server root.
@@ -164,7 +164,7 @@ module.exports = {
164164
};
165165
```
166166

167-
#### `Function`
167+
#### `Object`
168168

169169
Allow to filter `url()`. All filtered `url()` will not be resolved (left in the code as they were written).
170170

@@ -178,15 +178,17 @@ module.exports = {
178178
test: /\.css$/i,
179179
loader: "css-loader",
180180
options: {
181-
url: (url, resourcePath) => {
182-
// resourcePath - path to css file
181+
url: {
182+
filter: (url, resourcePath) => {
183+
// resourcePath - path to css file
183184

184-
// Don't handle `img.png` urls
185-
if (url.includes("img.png")) {
186-
return false;
187-
}
185+
// Don't handle `img.png` urls
186+
if (url.includes("img.png")) {
187+
return false;
188+
}
188189

189-
return true;
190+
return true;
191+
},
190192
},
191193
},
192194
},
@@ -197,7 +199,7 @@ module.exports = {
197199

198200
### `import`
199201

200-
Type: `Boolean|Function`
202+
Type: `Boolean|Object`
201203
Default: `true`
202204

203205
Enables/Disables `@import` at-rules handling.
@@ -245,7 +247,7 @@ module.exports = {
245247
};
246248
```
247249

248-
#### `Function`
250+
#### `Object`
249251

250252
Allow to filter `@import`. All filtered `@import` will not be resolved (left in the code as they were written).
251253

@@ -259,15 +261,17 @@ module.exports = {
259261
test: /\.css$/i,
260262
loader: "css-loader",
261263
options: {
262-
import: (url, media, resourcePath) => {
263-
// resourcePath - path to css file
264+
import: {
265+
filter: (url, media, resourcePath) => {
266+
// resourcePath - path to css file
264267

265-
// Don't handle `style.css` import
266-
if (url.includes("style.css")) {
267-
return false;
268-
}
268+
// Don't handle `style.css` import
269+
if (url.includes("style.css")) {
270+
return false;
271+
}
269272

270-
return true;
273+
return true;
274+
},
271275
},
272276
},
273277
},

src/index.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ export default async function loader(content, map, meta) {
6767
api: importPluginApi,
6868
context: this.context,
6969
rootContext: this.rootContext,
70-
filter: getFilter(options.import, this.resourcePath),
70+
filter: getFilter(options.import.filter, this.resourcePath),
7171
resolver,
7272
urlHandler: (url) =>
7373
stringifyRequest(
@@ -94,7 +94,7 @@ export default async function loader(content, map, meta) {
9494
replacements,
9595
context: this.context,
9696
rootContext: this.rootContext,
97-
filter: getFilter(options.url, this.resourcePath),
97+
filter: getFilter(options.url.filter, this.resourcePath),
9898
resolver: urlResolver,
9999
urlHandler: (url) => stringifyRequest(this, url),
100100
})

src/options.json

+14-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,13 @@
99
"type": "boolean"
1010
},
1111
{
12-
"instanceof": "Function"
12+
"type": "object",
13+
"properties": {
14+
"filter": {
15+
"instanceof": "Function"
16+
}
17+
},
18+
"additionalProperties": false
1319
}
1420
]
1521
},
@@ -20,7 +26,13 @@
2026
"type": "boolean"
2127
},
2228
{
23-
"instanceof": "Function"
29+
"type": "object",
30+
"properties": {
31+
"filter": {
32+
"instanceof": "Function"
33+
}
34+
},
35+
"additionalProperties": false
2436
}
2537
]
2638
},

test/__snapshots__/import-option.test.js.snap

+994-994
Large diffs are not rendered by default.

test/__snapshots__/url-option.test.js.snap

+1,159-1,159
Large diffs are not rendered by default.

test/__snapshots__/validate-options.test.js.snap

+72-4
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,48 @@ exports[`validate options should throw an error on the "esModule" option with "t
66
-> Use the ES modules syntax (https://github.com/webpack-contrib/css-loader#esmodule)."
77
`;
88

9+
exports[`validate options should throw an error on the "import" option with "() => {}" value 1`] = `
10+
"Invalid options object. CSS Loader has been initialized using an options object that does not match the API schema.
11+
- options.import should be one of these:
12+
boolean | object { filter? }
13+
-> Enables/Disables '@import' at-rules handling (https://github.com/webpack-contrib/css-loader#import).
14+
Details:
15+
* options.import should be a boolean.
16+
* options.import should be an object:
17+
object { filter? }"
18+
`;
19+
20+
exports[`validate options should throw an error on the "import" option with "[]" value 1`] = `
21+
"Invalid options object. CSS Loader has been initialized using an options object that does not match the API schema.
22+
- options.import should be one of these:
23+
boolean | object { filter? }
24+
-> Enables/Disables '@import' at-rules handling (https://github.com/webpack-contrib/css-loader#import).
25+
Details:
26+
* options.import should be a boolean.
27+
* options.import should be an object:
28+
object { filter? }"
29+
`;
30+
31+
exports[`validate options should throw an error on the "import" option with "{"filter":true}" value 1`] = `
32+
"Invalid options object. CSS Loader has been initialized using an options object that does not match the API schema.
33+
- options.import.filter should be an instance of function."
34+
`;
35+
36+
exports[`validate options should throw an error on the "import" option with "{}" value 1`] = `
37+
"Invalid options object. CSS Loader has been initialized using an options object that does not match the API schema.
38+
- options.import has an unknown property 'unknown'. These properties are valid:
39+
object { filter? }"
40+
`;
41+
942
exports[`validate options should throw an error on the "import" option with "true" value 1`] = `
1043
"Invalid options object. CSS Loader has been initialized using an options object that does not match the API schema.
1144
- options.import should be one of these:
12-
boolean | function
45+
boolean | object { filter? }
1346
-> Enables/Disables '@import' at-rules handling (https://github.com/webpack-contrib/css-loader#import).
1447
Details:
1548
* options.import should be a boolean.
16-
* options.import should be an instance of function."
49+
* options.import should be an object:
50+
object { filter? }"
1751
`;
1852

1953
exports[`validate options should throw an error on the "importLoaders" option with "2.5" value 1`] = `
@@ -278,12 +312,46 @@ exports[`validate options should throw an error on the "unknown" option with "tr
278312
object { url?, import?, modules?, sourceMap?, importLoaders?, esModule? }"
279313
`;
280314

315+
exports[`validate options should throw an error on the "url" option with "() => {}" value 1`] = `
316+
"Invalid options object. CSS Loader has been initialized using an options object that does not match the API schema.
317+
- options.url should be one of these:
318+
boolean | object { filter? }
319+
-> Enables/Disables 'url'/'image-set' functions handling (https://github.com/webpack-contrib/css-loader#url).
320+
Details:
321+
* options.url should be a boolean.
322+
* options.url should be an object:
323+
object { filter? }"
324+
`;
325+
326+
exports[`validate options should throw an error on the "url" option with "[]" value 1`] = `
327+
"Invalid options object. CSS Loader has been initialized using an options object that does not match the API schema.
328+
- options.url should be one of these:
329+
boolean | object { filter? }
330+
-> Enables/Disables 'url'/'image-set' functions handling (https://github.com/webpack-contrib/css-loader#url).
331+
Details:
332+
* options.url should be a boolean.
333+
* options.url should be an object:
334+
object { filter? }"
335+
`;
336+
337+
exports[`validate options should throw an error on the "url" option with "{"filter":true}" value 1`] = `
338+
"Invalid options object. CSS Loader has been initialized using an options object that does not match the API schema.
339+
- options.url.filter should be an instance of function."
340+
`;
341+
342+
exports[`validate options should throw an error on the "url" option with "{}" value 1`] = `
343+
"Invalid options object. CSS Loader has been initialized using an options object that does not match the API schema.
344+
- options.url has an unknown property 'unknown'. These properties are valid:
345+
object { filter? }"
346+
`;
347+
281348
exports[`validate options should throw an error on the "url" option with "true" value 1`] = `
282349
"Invalid options object. CSS Loader has been initialized using an options object that does not match the API schema.
283350
- options.url should be one of these:
284-
boolean | function
351+
boolean | object { filter? }
285352
-> Enables/Disables 'url'/'image-set' functions handling (https://github.com/webpack-contrib/css-loader#url).
286353
Details:
287354
* options.url should be a boolean.
288-
* options.url should be an instance of function."
355+
* options.url should be an object:
356+
object { filter? }"
289357
`;

test/import-option.test.js

+14-12
Original file line numberDiff line numberDiff line change
@@ -53,23 +53,25 @@ describe('"import" option', () => {
5353
expect(getErrors(stats)).toMatchSnapshot("errors");
5454
});
5555

56-
it('should work when "Function"', async () => {
56+
it("should work with import.filter", async () => {
5757
const compiler = getCompiler("./import/import.js", {
58-
import: (url, media, resourcePath) => {
59-
expect(url).toBeDefined();
58+
import: {
59+
filter: (url, media, resourcePath) => {
60+
expect(url).toBeDefined();
6061

61-
if (url === "test-nested-media.css") {
62-
expect(media).toBeDefined();
63-
}
62+
if (url === "test-nested-media.css") {
63+
expect(media).toBeDefined();
64+
}
6465

65-
expect(resourcePath).toBeDefined();
66+
expect(resourcePath).toBeDefined();
6667

67-
// Don't handle `test.css`
68-
if (url.includes("test.css")) {
69-
return false;
70-
}
68+
// Don't handle `test.css`
69+
if (url.includes("test.css")) {
70+
return false;
71+
}
7172

72-
return true;
73+
return true;
74+
},
7375
},
7476
});
7577
const stats = await compile(compiler);

test/url-option.test.js

+13-11
Original file line numberDiff line numberDiff line change
@@ -50,21 +50,23 @@ describe('"url" option', () => {
5050
expect(getErrors(stats)).toMatchSnapshot("errors");
5151
});
5252

53-
it('should work with a value equal to "Function"', async () => {
53+
it("should work with url.filter", async () => {
5454
const compiler = getCompiler("./url/url.js", {
55-
url: (url, resourcePath) => {
56-
expect(typeof resourcePath === "string").toBe(true);
55+
url: {
56+
filter: (url, resourcePath) => {
57+
expect(typeof resourcePath === "string").toBe(true);
5758

58-
if (url.startsWith("/guide/img")) {
59-
return false;
60-
}
59+
if (url.startsWith("/guide/img")) {
60+
return false;
61+
}
6162

62-
// Don't handle `img.png`
63-
if (url.includes("img.png")) {
64-
return false;
65-
}
63+
// Don't handle `img.png`
64+
if (url.includes("img.png")) {
65+
return false;
66+
}
6667

67-
return true;
68+
return true;
69+
},
6870
},
6971
});
7072
const stats = await compile(compiler);

test/validate-options.test.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ import { getCompiler, compile } from "./helpers/index";
33
describe("validate options", () => {
44
const tests = {
55
url: {
6-
success: [true, false, () => {}],
7-
failure: ["true"],
6+
success: [true, false, { filter: () => true }],
7+
failure: ["true", [], () => {}, { filter: true }, { unknown: () => {} }],
88
},
99
import: {
10-
success: [true, false, () => {}],
11-
failure: ["true"],
10+
success: [true, false, { filter: () => true }],
11+
failure: ["true", [], () => {}, { filter: true }, { unknown: () => {} }],
1212
},
1313
modules: {
1414
success: [

0 commit comments

Comments
 (0)