Skip to content

Commit 8a87359

Browse files
feat(import): add @import filter support (options.import)
1 parent f4453d2 commit 8a87359

File tree

11 files changed

+188
-16
lines changed

11 files changed

+188
-16
lines changed

README.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,44 @@ To disable `@import` resolving by `css-loader` set the option to `false`
118118
}
119119
```
120120

121+
#### `{String}`
122+
123+
**webpack.config.js**
124+
```js
125+
{
126+
loader: 'css-loader',
127+
options: {
128+
import: 'filter'
129+
}
130+
}
131+
```
132+
133+
#### `{RegExp}`
134+
135+
**webpack.config.js**
136+
```js
137+
{
138+
loader: 'css-loader',
139+
options: {
140+
import: /filter/
141+
}
142+
}
143+
```
144+
145+
#### `{Function}`
146+
147+
**webpack.config.js**
148+
```js
149+
{
150+
loader: 'css-loader',
151+
options: {
152+
import (url) {
153+
return /filter/.test(url)
154+
}
155+
}
156+
}
157+
```
158+
121159
### `minimize`
122160

123161
#### `{Boolean}`

src/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export default function loader(src, map, meta) {
5555

5656
// CSS Import Plugin
5757
if (options.import) {
58-
plugins.push(imports());
58+
plugins.push(imports(options));
5959
}
6060

6161
// CSS Minifier

src/lib/plugins/import.js

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,43 @@ const parseImport = (params) => {
4040
};
4141
};
4242

43-
const isExternalUrl = url => /^\w+:\/\//.test(url) || url.startsWith('//');
43+
const URL = /^\w+:\/\//;
44+
45+
const filter = (url, options) => {
46+
if (URL.test(url)) {
47+
return true;
48+
}
49+
50+
if (url.startsWith('//')) {
51+
return true;
52+
}
53+
54+
if (typeof options.import === 'string') {
55+
return url.includes(options.import);
56+
}
57+
58+
if (options.import instanceof RegExp) {
59+
return options.import.test(url);
60+
}
4461

45-
const walkImports = (css, callback) => {
62+
if (typeof options.import === 'function') {
63+
return options.import(url);
64+
}
65+
66+
return false;
67+
}
68+
69+
const walkImports = (css, cb) => {
4670
css.each((node) => {
4771
if (node.type === 'atrule' && node.name.toLowerCase() === 'import') {
48-
callback(node);
72+
cb(node);
4973
}
5074
});
5175
};
5276

53-
export default postcss.plugin(plugin, () => (css, result) => {
77+
export default postcss.plugin(plugin, (options) => (css, result) => {
5478
let idx = 0;
79+
5580
const imports = {};
5681

5782
walkImports(css, (atrule) => {
@@ -65,12 +90,12 @@ export default postcss.plugin(plugin, () => (css, result) => {
6590
const parsed = parseImport(atrule.params);
6691

6792
if (parsed === null) {
68-
return result.warn(`Unable to find uri in '${atrule.toString()}'`, {
93+
return result.warn(`Unable to find URI in '${atrule.toString()}'`, {
6994
node: atrule,
7095
});
7196
}
7297

73-
if (!isExternalUrl(parsed.url)) {
98+
if (!filter(parsed.url, options)) {
7499
atrule.remove();
75100

76101
imports[`CSS__IMPORT__${idx}`] = `${parsed.url}`;
@@ -87,12 +112,6 @@ export default postcss.plugin(plugin, () => (css, result) => {
87112

88113
result.messages.push({ imports });
89114

90-
// result.messages.push({
91-
// type: 'dependency',
92-
// plugin: 'postcss-icss-import',
93-
// imports
94-
// })
95-
96115
// ICSS {String}
97116
// css.prepend(createICSSRules(imports, {}));
98117
});

src/options.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@
55
"type": "boolean"
66
},
77
"import": {
8-
"type": "boolean"
8+
"anyOf": [
9+
{ "type": "string" },
10+
{ "type": "boolean" },
11+
{ "instanceof": "RegExp" },
12+
{ "instanceof": "Function" }
13+
]
914
},
1015
"minimize": {
1116
"type": "boolean"
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
@import './import.css';
2+
@import './filter/import.css';
3+
4+
.css {
5+
width: 100%;
6+
}
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
11
import css from './fixture.css';
22

3-
export default css;
File renamed without changes.

test/fixtures/import/fixture.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import css from './fixture.css';
File renamed without changes.

test/options/__snapshots__/import.test.js.snap

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,57 @@ export default \`.fixture {
1515
}
1616
\`"
1717
`;
18+
19+
exports[`Options import {Function} 1`] = `
20+
"// CSS Imports
21+
import CSS__IMPORT__0 from './import.css';
22+
23+
24+
// CSS Exports
25+
// CSS Modules Exports
26+
27+
28+
// CSS
29+
export default \`@import './filter/import.css';
30+
31+
.css {
32+
width: 100%;
33+
}
34+
\`"
35+
`;
36+
37+
exports[`Options import {RegExp} 1`] = `
38+
"// CSS Imports
39+
import CSS__IMPORT__0 from './import.css';
40+
41+
42+
// CSS Exports
43+
// CSS Modules Exports
44+
45+
46+
// CSS
47+
export default \`@import './filter/import.css';
48+
49+
.css {
50+
width: 100%;
51+
}
52+
\`"
53+
`;
54+
55+
exports[`Options import {String} 1`] = `
56+
"// CSS Imports
57+
import CSS__IMPORT__0 from './import.css';
58+
59+
60+
// CSS Exports
61+
// CSS Modules Exports
62+
63+
64+
// CSS
65+
export default \`@import './filter/import.css';
66+
67+
.css {
68+
width: 100%;
69+
}
70+
\`"
71+
`;

test/options/import.test.js

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,57 @@ describe('Options', () => {
1313
},
1414
};
1515

16-
const stats = await webpack('imports/fixture.js', config);
16+
const stats = await webpack('import/fixture.js', config);
17+
const { source } = stats.toJson().modules[1];
18+
19+
expect(source).toMatchSnapshot();
20+
});
21+
22+
test('{String}', async () => {
23+
const config = {
24+
loader: {
25+
test: /\.css$/,
26+
options: {
27+
import: 'filter'
28+
},
29+
},
30+
};
31+
32+
const stats = await webpack('import/filter/fixture.js', config);
33+
const { source } = stats.toJson().modules[1];
34+
35+
expect(source).toMatchSnapshot();
36+
});
37+
38+
test('{RegExp}', async () => {
39+
const config = {
40+
loader: {
41+
test: /\.css$/,
42+
options: {
43+
import: /filter/
44+
},
45+
},
46+
};
47+
48+
const stats = await webpack('import/filter/fixture.js', config);
49+
const { source } = stats.toJson().modules[1];
50+
51+
expect(source).toMatchSnapshot();
52+
});
53+
54+
test('{Function}', async () => {
55+
const config = {
56+
loader: {
57+
test: /\.css$/,
58+
options: {
59+
import (url) {
60+
return /filter/.test(url)
61+
}
62+
},
63+
},
64+
};
65+
66+
const stats = await webpack('import/filter/fixture.js', config);
1767
const { source } = stats.toJson().modules[1];
1868

1969
expect(source).toMatchSnapshot();

0 commit comments

Comments
 (0)