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: allow modules.auto to be a filter function #1086

Merged
merged 1 commit into from Jun 3, 2020
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
28 changes: 26 additions & 2 deletions README.md
Expand Up @@ -542,7 +542,7 @@ module.exports = {

##### `auto`

Type: `Boolean|RegExp`
Type: `Boolean|RegExp|Function`
Default: `'undefined'`

Allows auto enable css modules based on filename.
Expand Down Expand Up @@ -576,7 +576,7 @@ module.exports = {

###### `RegExp`

Enable css modules for files based on a filename and satisfying your regex.
Enable css modules for files based on the filename satisfying your regex check.

**webpack.config.js**

Expand All @@ -598,6 +598,30 @@ module.exports = {
};
```

###### `Function`

Enable css modules for files based on the filename satisfying your filter function check.

**webpack.config.js**

```js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: 'css-loader',
options: {
modules: {
auto: (resourcePath) => resourcePath.endsWith('.custom-module.css'),
},
},
},
],
},
};
```

##### `mode`

Type: `String|Function`
Expand Down
3 changes: 3 additions & 0 deletions src/options.json
Expand Up @@ -41,6 +41,9 @@
{
"instanceof": "RegExp"
},
{
"instanceof": "Function"
},
{
"type": "boolean"
}
Expand Down
4 changes: 4 additions & 0 deletions src/utils.js
Expand Up @@ -117,6 +117,10 @@ function shouldUseModulesPlugins(modules, resourcePath) {
return modules.auto.test(resourcePath);
}

if (typeof modules.auto === 'function') {
return modules.auto(resourcePath);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use typeof


return true;
}

Expand Down
91 changes: 75 additions & 16 deletions test/__snapshots__/modules-option.test.js.snap
Expand Up @@ -3148,9 +3148,9 @@ Array [

exports[`"modules" option should work when the "getLocalIdent" option returns "false": warnings 1`] = `Array []`;

exports[`"modules" option should work with a modules.auto equal "false": errors 1`] = `Array []`;
exports[`"modules" option should work with a modules.auto Boolean that is "false": errors 1`] = `Array []`;

exports[`"modules" option should work with a modules.auto equal "false": module 1`] = `
exports[`"modules" option should work with a modules.auto Boolean that is "false": module 1`] = `
"// Imports
var ___CSS_LOADER_API_IMPORT___ = require(\\"../../../../src/runtime/api.js\\");
exports = ___CSS_LOADER_API_IMPORT___(false);
Expand All @@ -3161,7 +3161,7 @@ module.exports = exports;
"
`;

exports[`"modules" option should work with a modules.auto equal "false": result 1`] = `
exports[`"modules" option should work with a modules.auto Boolean that is "false": result 1`] = `
Array [
Array [
"./modules/mode/relative.module.css",
Expand All @@ -3174,11 +3174,11 @@ Array [
]
`;

exports[`"modules" option should work with a modules.auto equal "false": warnings 1`] = `Array []`;
exports[`"modules" option should work with a modules.auto Boolean that is "false": warnings 1`] = `Array []`;

exports[`"modules" option should work with a modules.auto equal "true": errors 1`] = `Array []`;
exports[`"modules" option should work with a modules.auto Boolean that is "true": errors 1`] = `Array []`;

exports[`"modules" option should work with a modules.auto equal "true": module 1`] = `
exports[`"modules" option should work with a modules.auto Boolean that is "true": module 1`] = `
"// Imports
var ___CSS_LOADER_API_IMPORT___ = require(\\"../../../../src/runtime/api.js\\");
exports = ___CSS_LOADER_API_IMPORT___(false);
Expand All @@ -3192,7 +3192,7 @@ module.exports = exports;
"
`;

exports[`"modules" option should work with a modules.auto equal "true": result 1`] = `
exports[`"modules" option should work with a modules.auto Boolean that is "true": result 1`] = `
Array [
Array [
"./modules/mode/relative.module.css",
Expand All @@ -3205,11 +3205,11 @@ Array [
]
`;

exports[`"modules" option should work with a modules.auto equal "true": warnings 1`] = `Array []`;
exports[`"modules" option should work with a modules.auto Boolean that is "true": warnings 1`] = `Array []`;

exports[`"modules" option should work with a modules.auto returns "false": errors 1`] = `Array []`;
exports[`"modules" option should work with a modules.auto Function that returns "false": errors 1`] = `Array []`;

exports[`"modules" option should work with a modules.auto returns "false": module 1`] = `
exports[`"modules" option should work with a modules.auto Function that returns "false": module 1`] = `
"// Imports
var ___CSS_LOADER_API_IMPORT___ = require(\\"../../../../src/runtime/api.js\\");
exports = ___CSS_LOADER_API_IMPORT___(false);
Expand All @@ -3220,7 +3220,7 @@ module.exports = exports;
"
`;

exports[`"modules" option should work with a modules.auto returns "false": result 1`] = `
exports[`"modules" option should work with a modules.auto Function that returns "false": result 1`] = `
Array [
Array [
"./modules/mode/relative.module.css",
Expand All @@ -3233,11 +3233,11 @@ Array [
]
`;

exports[`"modules" option should work with a modules.auto returns "false": warnings 1`] = `Array []`;
exports[`"modules" option should work with a modules.auto Function that returns "false": warnings 1`] = `Array []`;

exports[`"modules" option should work with a modules.auto returns "true": errors 1`] = `Array []`;
exports[`"modules" option should work with a modules.auto Function that returns "true": errors 1`] = `Array []`;

exports[`"modules" option should work with a modules.auto returns "true": module 1`] = `
exports[`"modules" option should work with a modules.auto Function that returns "true": module 1`] = `
"// Imports
var ___CSS_LOADER_API_IMPORT___ = require(\\"../../../../src/runtime/api.js\\");
exports = ___CSS_LOADER_API_IMPORT___(false);
Expand All @@ -3251,7 +3251,7 @@ module.exports = exports;
"
`;

exports[`"modules" option should work with a modules.auto returns "true": result 1`] = `
exports[`"modules" option should work with a modules.auto Function that returns "true": result 1`] = `
Array [
Array [
"./modules/mode/relative.module.css",
Expand All @@ -3264,7 +3264,66 @@ Array [
]
`;

exports[`"modules" option should work with a modules.auto returns "true": warnings 1`] = `Array []`;
exports[`"modules" option should work with a modules.auto Function that returns "true": warnings 1`] = `Array []`;

exports[`"modules" option should work with a modules.auto RegExp that returns "false": errors 1`] = `Array []`;

exports[`"modules" option should work with a modules.auto RegExp that returns "false": module 1`] = `
"// Imports
var ___CSS_LOADER_API_IMPORT___ = require(\\"../../../../src/runtime/api.js\\");
exports = ___CSS_LOADER_API_IMPORT___(false);
// Module
exports.push([module.id, \\".relative {\\\\n color: red;\\\\n}\\\\n\\", \\"\\"]);
// Exports
module.exports = exports;
"
`;

exports[`"modules" option should work with a modules.auto RegExp that returns "false": result 1`] = `
Array [
Array [
"./modules/mode/relative.module.css",
".relative {
color: red;
}
",
"",
],
]
`;

exports[`"modules" option should work with a modules.auto RegExp that returns "false": warnings 1`] = `Array []`;

exports[`"modules" option should work with a modules.auto RegExp that returns "true": errors 1`] = `Array []`;

exports[`"modules" option should work with a modules.auto RegExp that returns "true": module 1`] = `
"// Imports
var ___CSS_LOADER_API_IMPORT___ = require(\\"../../../../src/runtime/api.js\\");
exports = ___CSS_LOADER_API_IMPORT___(false);
// Module
exports.push([module.id, \\".y35Nud52-ZFXmqL6AWueX {\\\\n color: red;\\\\n}\\\\n\\", \\"\\"]);
// Exports
exports.locals = {
\\"relative\\": \\"y35Nud52-ZFXmqL6AWueX\\"
};
module.exports = exports;
"
`;

exports[`"modules" option should work with a modules.auto RegExp that returns "true": result 1`] = `
Array [
Array [
"./modules/mode/relative.module.css",
".y35Nud52-ZFXmqL6AWueX {
color: red;
}
",
"",
],
]
`;

exports[`"modules" option should work with a modules.auto RegExp that returns "true": warnings 1`] = `Array []`;

exports[`"modules" option should work with case \`animation\` (\`modules\` value is \`false)\`: errors 1`] = `Array []`;

Expand Down
14 changes: 14 additions & 0 deletions test/__snapshots__/validate-options.test.js.snap
Expand Up @@ -43,6 +43,20 @@ exports[`validate options should throw an error on the "localsConvention" option
-> Style of exported classnames (https://github.com/webpack-contrib/css-loader#localsconvention)."
`;

exports[`validate options should throw an error on the "modules" option with "{"auto":"invalid"}" value 1`] = `
"Invalid options object. CSS Loader has been initialized using an options object that does not match the API schema.
- options.modules should be one of these:
boolean | \\"local\\" | \\"global\\" | \\"pure\\" | object { auto?, mode?, exportGlobals?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? }
-> Enables/Disables CSS Modules and their configuration (https://github.com/webpack-contrib/css-loader#modules).
Details:
* options.modules.auto should be one of these:
RegExp | function | boolean
Details:
* options.modules.auto should be an instance of RegExp.
* options.modules.auto should be an instance of function.
* options.modules.auto should be a boolean."
`;

exports[`validate options should throw an error on the "modules" option with "{"context":true}" value 1`] = `
"Invalid options object. CSS Loader has been initialized using an options object that does not match the API schema.
- options.modules.context should be a string."
Expand Down
44 changes: 40 additions & 4 deletions test/modules-option.test.js
Expand Up @@ -689,7 +689,7 @@ describe('"modules" option', () => {
expect(getErrors(stats)).toMatchSnapshot('errors');
});

it('should work with a modules.auto equal "false"', async () => {
it('should work with a modules.auto Boolean that is "false"', async () => {
const compiler = getCompiler('./modules/mode/modules.js', {
modules: {
auto: false,
Expand All @@ -707,7 +707,7 @@ describe('"modules" option', () => {
expect(getErrors(stats)).toMatchSnapshot('errors');
});

it('should work with a modules.auto equal "true"', async () => {
it('should work with a modules.auto Boolean that is "true"', async () => {
const compiler = getCompiler('./modules/mode/modules.js', {
modules: {
auto: true,
Expand All @@ -725,7 +725,7 @@ describe('"modules" option', () => {
expect(getErrors(stats)).toMatchSnapshot('errors');
});

it('should work with a modules.auto returns "true"', async () => {
it('should work with a modules.auto RegExp that returns "true"', async () => {
const compiler = getCompiler('./modules/mode/modules.js', {
modules: {
auto: /relative.module.css$/,
Expand All @@ -743,7 +743,7 @@ describe('"modules" option', () => {
expect(getErrors(stats)).toMatchSnapshot('errors');
});

it('should work with a modules.auto returns "false"', async () => {
it('should work with a modules.auto RegExp that returns "false"', async () => {
const compiler = getCompiler('./modules/mode/modules.js', {
modules: {
auto: /will no pass/,
Expand All @@ -760,4 +760,40 @@ describe('"modules" option', () => {
expect(getWarnings(stats)).toMatchSnapshot('warnings');
expect(getErrors(stats)).toMatchSnapshot('errors');
});

it('should work with a modules.auto Function that returns "true"', async () => {
const compiler = getCompiler('./modules/mode/modules.js', {
modules: {
auto: (relativePath) => relativePath.endsWith('module.css'),
},
});
const stats = await compile(compiler);

expect(
getModuleSource('./modules/mode/relative.module.css', stats)
).toMatchSnapshot('module');
expect(getExecutedCode('main.bundle.js', compiler, stats)).toMatchSnapshot(
'result'
);
expect(getWarnings(stats)).toMatchSnapshot('warnings');
expect(getErrors(stats)).toMatchSnapshot('errors');
});

it('should work with a modules.auto Function that returns "false"', async () => {
const compiler = getCompiler('./modules/mode/modules.js', {
modules: {
auto: (relativePath) => relativePath.endsWith('will no pass'),
},
});
const stats = await compile(compiler);

expect(
getModuleSource('./modules/mode/relative.module.css', stats)
).toMatchSnapshot('module');
expect(getExecutedCode('main.bundle.js', compiler, stats)).toMatchSnapshot(
'result'
);
expect(getWarnings(stats)).toMatchSnapshot('warnings');
expect(getErrors(stats)).toMatchSnapshot('errors');
});
});
5 changes: 5 additions & 0 deletions test/validate-options.test.js
Expand Up @@ -28,6 +28,10 @@ describe('validate options', () => {
{ localIdentRegExp: 'page-(.*)\\.js' },
{ localIdentRegExp: /page-(.*)\.js/ },
{ exportGlobals: true },
{ auto: true },
{ auto: false },
{ auto: /custom-regex/ },
{ auto: () => true },
],
failure: [
'true',
Expand All @@ -44,6 +48,7 @@ describe('validate options', () => {
{ getLocalIdent: [] },
{ localIdentRegExp: true },
{ exportGlobals: 'invalid' },
{ auto: 'invalid' },
],
},
sourceMap: {
Expand Down