Skip to content

Commit f9aa73c

Browse files
feat: import option doesn't affect on composes (#822)
BREAKING CHANGE: `import` option only affect on `@import` at-rules and doesn't affect on `composes` declarations
1 parent 3b573a9 commit f9aa73c

File tree

7 files changed

+137
-29
lines changed

7 files changed

+137
-29
lines changed

Diff for: README.md

+4-8
Original file line numberDiff line numberDiff line change
@@ -116,20 +116,16 @@ url(~module/image.png) => require('module/image.png')
116116

117117
### `import`
118118

119-
To import styles from a node module path, prefix it with a `~`:
119+
To disable `@import` resolving by `css-loader` set the option to `false`.
120120

121-
```css
122-
@import '~module/styles.css';
123-
```
121+
Absolute urls are not resolving.
124122

125-
To disable `@import` resolving by `css-loader` set the option to `false`
123+
To import styles from a node module path, prefix it with a `~`:
126124

127125
```css
128-
@import url('https://fonts.googleapis.com/css?family=Roboto');
126+
@import '~module/styles.css';
129127
```
130128

131-
> _⚠️ Use with caution, since this disables resolving for **all** `@import`s, including css modules `composes: xxx from 'path/to/file.css'` feature._
132-
133129
### [`modules`](https://github.com/css-modules/css-modules)
134130

135131
The query parameter `modules` enables the **CSS Modules** spec.

Diff for: lib/loader.js

+10-5
Original file line numberDiff line numberDiff line change
@@ -60,16 +60,21 @@ module.exports = function loader(content, map) {
6060
return true;
6161
})
6262
.map((imp) => {
63-
if (!loaderUtils.isUrlRequest(imp.url)) {
63+
const { url } = imp;
64+
const media = imp.media || '';
65+
66+
if (!loaderUtils.isUrlRequest(url)) {
6467
return `exports.push([module.id, ${JSON.stringify(
65-
`@import url(${imp.url});`
66-
)}, ${JSON.stringify(imp.media)}]);`;
68+
`@import url(${url});`
69+
)}, ${JSON.stringify(media)}]);`;
6770
}
68-
const importUrl = importUrlPrefix + imp.url;
71+
72+
const importUrl = importUrlPrefix + url;
73+
6974
return `exports.i(require(${loaderUtils.stringifyRequest(
7075
this,
7176
importUrl
72-
)}), ${JSON.stringify(imp.media)});`;
77+
)}), ${JSON.stringify(media)});`;
7378
}, this)
7479
.join('\n');
7580

Diff for: lib/plugins/postcss-icss-parser.js

+13-16
Original file line numberDiff line numberDiff line change
@@ -28,26 +28,23 @@ module.exports = postcss.plugin(
2828
});
2929

3030
function replaceImportsInString(str) {
31-
if (options.import) {
32-
const tokens = valueParser(str);
31+
const tokens = valueParser(str);
3332

34-
tokens.walk((node) => {
35-
if (node.type !== 'word') {
36-
return;
37-
}
33+
tokens.walk((node) => {
34+
if (node.type !== 'word') {
35+
return;
36+
}
3837

39-
const token = node.value;
40-
const importIndex = imports[`$${token}`];
38+
const token = node.value;
39+
const importIndex = imports[`$${token}`];
4140

42-
if (typeof importIndex === 'number') {
43-
// eslint-disable-next-line no-param-reassign
44-
node.value = `___CSS_LOADER_IMPORT___${importIndex}___`;
45-
}
46-
});
41+
if (typeof importIndex === 'number') {
42+
// eslint-disable-next-line no-param-reassign
43+
node.value = `___CSS_LOADER_IMPORT___${importIndex}___`;
44+
}
45+
});
4746

48-
return tokens.toString();
49-
}
50-
return str;
47+
return tokens.toString();
5148
}
5249

5350
// Replace tokens in declarations

Diff for: test/__snapshots__/import-option.test.js.snap

+79
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,84 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3+
exports[`import option false and modules false: errors 1`] = `Array []`;
4+
5+
exports[`import option false and modules false: module (evaluated) 1`] = `
6+
Array [
7+
Array [
8+
2,
9+
"
10+
",
11+
"",
12+
],
13+
Array [
14+
1,
15+
"@import url(test-other.css) (min-width: 100px);
16+
17+
.ghi {
18+
color: red;
19+
}
20+
",
21+
"",
22+
],
23+
]
24+
`;
25+
26+
exports[`import option false and modules false: module 1`] = `
27+
"exports = module.exports = require(\\"../../../lib/runtime/api.js\\")(false);
28+
// imports
29+
exports.i(require(\\"-!../../../index.js??ref--4-0!./values.css\\"), \\"\\");
30+
31+
// module
32+
exports.push([module.id, \\"@import url(test-other.css) (min-width: 100px);\\\\n\\\\n.ghi {\\\\n color: \\" + require(\\"-!../../../index.js??ref--4-0!./values.css\\").locals[\\"def\\"] + \\";\\\\n}\\\\n\\", \\"\\"]);
33+
34+
// exports
35+
exports.locals = {
36+
\\"def\\": \\"\\" + require(\\"-!../../../index.js??ref--4-0!./values.css\\").locals[\\"def\\"] + \\"\\"
37+
};"
38+
`;
39+
40+
exports[`import option false and modules false: warnings 1`] = `Array []`;
41+
42+
exports[`import option false and modules true: errors 1`] = `Array []`;
43+
44+
exports[`import option false and modules true: module (evaluated) 1`] = `
45+
Array [
46+
Array [
47+
2,
48+
"
49+
",
50+
"",
51+
],
52+
Array [
53+
1,
54+
"@import url(test-other.css) (min-width: 100px);
55+
56+
._3r49KZIIAltPknAjdNVZ-7 {
57+
color: red;
58+
}
59+
",
60+
"",
61+
],
62+
]
63+
`;
64+
65+
exports[`import option false and modules true: module 1`] = `
66+
"exports = module.exports = require(\\"../../../lib/runtime/api.js\\")(false);
67+
// imports
68+
exports.i(require(\\"-!../../../index.js??ref--4-0!./values.css\\"), \\"\\");
69+
70+
// module
71+
exports.push([module.id, \\"@import url(test-other.css) (min-width: 100px);\\\\n\\\\n._3r49KZIIAltPknAjdNVZ-7 {\\\\n color: \\" + require(\\"-!../../../index.js??ref--4-0!./values.css\\").locals[\\"def\\"] + \\";\\\\n}\\\\n\\", \\"\\"]);
72+
73+
// exports
74+
exports.locals = {
75+
\\"def\\": \\"\\" + require(\\"-!../../../index.js??ref--4-0!./values.css\\").locals[\\"def\\"] + \\"\\",
76+
\\"ghi\\": \\"_3r49KZIIAltPknAjdNVZ-7\\"
77+
};"
78+
`;
79+
80+
exports[`import option false and modules true: warnings 1`] = `Array []`;
81+
382
exports[`import option false: errors 1`] = `Array []`;
483
584
exports[`import option false: module (evaluated) 1`] = `

Diff for: test/fixtures/import/css-modules.css

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
@import url(test-other.css) (min-width: 100px);
2+
3+
@value def from './values.css';
4+
5+
.ghi {
6+
color: def;
7+
}

Diff for: test/fixtures/import/values.css

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
@value def: red;

Diff for: test/import-option.test.js

+23
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,27 @@ describe('import option', () => {
3131
expect(stats.compilation.warnings).toMatchSnapshot('warnings');
3232
expect(stats.compilation.errors).toMatchSnapshot('errors');
3333
});
34+
35+
[true, false].forEach((modulesValue) => {
36+
it(`false and modules ${modulesValue}`, async () => {
37+
const config = {
38+
loader: { options: { import: false, modules: modulesValue } },
39+
};
40+
const testId = './import/css-modules.css';
41+
const stats = await webpack(testId, config);
42+
const { modules } = stats.toJson();
43+
const module = modules.find((m) => m.id === testId);
44+
45+
expect(module.source).toMatchSnapshot('module');
46+
expect(evaluated(module.source, modules)).toMatchSnapshot(
47+
'module (evaluated)'
48+
);
49+
expect(normalizeErrors(stats.compilation.warnings)).toMatchSnapshot(
50+
'warnings'
51+
);
52+
expect(normalizeErrors(stats.compilation.errors)).toMatchSnapshot(
53+
'errors'
54+
);
55+
});
56+
});
3457
});

0 commit comments

Comments
 (0)