Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: import option doesn't affect on composes #822

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 4 additions & 8 deletions README.md
Expand Up @@ -116,20 +116,16 @@ url(~module/image.png) => require('module/image.png')

### `import`

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

```css
@import '~module/styles.css';
```
Absolute urls are not resolving.

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

```css
@import url('https://fonts.googleapis.com/css?family=Roboto');
@import '~module/styles.css';
```

> _⚠️ Use with caution, since this disables resolving for **all** `@import`s, including css modules `composes: xxx from 'path/to/file.css'` feature._

### [`modules`](https://github.com/css-modules/css-modules)

The query parameter `modules` enables the **CSS Modules** spec.
Expand Down
15 changes: 10 additions & 5 deletions lib/loader.js
Expand Up @@ -60,16 +60,21 @@ module.exports = function loader(content, map) {
return true;
})
.map((imp) => {
if (!loaderUtils.isUrlRequest(imp.url)) {
const { url } = imp;
const media = imp.media || '';

if (!loaderUtils.isUrlRequest(url)) {
return `exports.push([module.id, ${JSON.stringify(
`@import url(${imp.url});`
)}, ${JSON.stringify(imp.media)}]);`;
`@import url(${url});`
)}, ${JSON.stringify(media)}]);`;
}
const importUrl = importUrlPrefix + imp.url;

const importUrl = importUrlPrefix + url;

return `exports.i(require(${loaderUtils.stringifyRequest(
this,
importUrl
)}), ${JSON.stringify(imp.media)});`;
)}), ${JSON.stringify(media)});`;
}, this)
.join('\n');

Expand Down
29 changes: 13 additions & 16 deletions lib/plugins/postcss-icss-parser.js
Expand Up @@ -28,26 +28,23 @@ module.exports = postcss.plugin(
});

function replaceImportsInString(str) {
if (options.import) {
const tokens = valueParser(str);
const tokens = valueParser(str);

tokens.walk((node) => {
if (node.type !== 'word') {
return;
}
tokens.walk((node) => {
if (node.type !== 'word') {
return;
}

const token = node.value;
const importIndex = imports[`$${token}`];
const token = node.value;
const importIndex = imports[`$${token}`];

if (typeof importIndex === 'number') {
// eslint-disable-next-line no-param-reassign
node.value = `___CSS_LOADER_IMPORT___${importIndex}___`;
}
});
if (typeof importIndex === 'number') {
// eslint-disable-next-line no-param-reassign
node.value = `___CSS_LOADER_IMPORT___${importIndex}___`;
}
});

return tokens.toString();
}
return str;
return tokens.toString();
}

// Replace tokens in declarations
Expand Down
79 changes: 79 additions & 0 deletions test/__snapshots__/import-option.test.js.snap
@@ -1,5 +1,84 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`import option false and modules false: errors 1`] = `Array []`;

exports[`import option false and modules false: module (evaluated) 1`] = `
Array [
Array [
2,
"
",
"",
],
Array [
1,
"@import url(test-other.css) (min-width: 100px);

.ghi {
color: red;
}
",
"",
],
]
`;

exports[`import option false and modules false: module 1`] = `
"exports = module.exports = require(\\"../../../lib/runtime/api.js\\")(false);
// imports
exports.i(require(\\"-!../../../index.js??ref--4-0!./values.css\\"), \\"\\");

// module
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\\", \\"\\"]);

// exports
exports.locals = {
\\"def\\": \\"\\" + require(\\"-!../../../index.js??ref--4-0!./values.css\\").locals[\\"def\\"] + \\"\\"
};"
`;

exports[`import option false and modules false: warnings 1`] = `Array []`;

exports[`import option false and modules true: errors 1`] = `Array []`;

exports[`import option false and modules true: module (evaluated) 1`] = `
Array [
Array [
2,
"
",
"",
],
Array [
1,
"@import url(test-other.css) (min-width: 100px);

._3r49KZIIAltPknAjdNVZ-7 {
color: red;
}
",
"",
],
]
`;

exports[`import option false and modules true: module 1`] = `
"exports = module.exports = require(\\"../../../lib/runtime/api.js\\")(false);
// imports
exports.i(require(\\"-!../../../index.js??ref--4-0!./values.css\\"), \\"\\");

// module
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\\", \\"\\"]);

// exports
exports.locals = {
\\"def\\": \\"\\" + require(\\"-!../../../index.js??ref--4-0!./values.css\\").locals[\\"def\\"] + \\"\\",
\\"ghi\\": \\"_3r49KZIIAltPknAjdNVZ-7\\"
};"
`;

exports[`import option false and modules true: warnings 1`] = `Array []`;

exports[`import option false: errors 1`] = `Array []`;

exports[`import option false: module (evaluated) 1`] = `
Expand Down
7 changes: 7 additions & 0 deletions test/fixtures/import/css-modules.css
@@ -0,0 +1,7 @@
@import url(test-other.css) (min-width: 100px);

@value def from './values.css';

.ghi {
color: def;
}
1 change: 1 addition & 0 deletions test/fixtures/import/values.css
@@ -0,0 +1 @@
@value def: red;
23 changes: 23 additions & 0 deletions test/import-option.test.js
Expand Up @@ -31,4 +31,27 @@ describe('import option', () => {
expect(stats.compilation.warnings).toMatchSnapshot('warnings');
expect(stats.compilation.errors).toMatchSnapshot('errors');
});

[true, false].forEach((modulesValue) => {
it(`false and modules ${modulesValue}`, async () => {
const config = {
loader: { options: { import: false, modules: modulesValue } },
};
const testId = './import/css-modules.css';
const stats = await webpack(testId, config);
const { modules } = stats.toJson();
const module = modules.find((m) => m.id === testId);

expect(module.source).toMatchSnapshot('module');
expect(evaluated(module.source, modules)).toMatchSnapshot(
'module (evaluated)'
);
expect(normalizeErrors(stats.compilation.warnings)).toMatchSnapshot(
'warnings'
);
expect(normalizeErrors(stats.compilation.errors)).toMatchSnapshot(
'errors'
);
});
});
});