Skip to content

Commit

Permalink
feat: allow modules.auto to be a filter function (#1086)
Browse files Browse the repository at this point in the history
  • Loading branch information
BPScott authored Jun 3, 2020
1 parent 505d2e6 commit 0902353
Show file tree
Hide file tree
Showing 7 changed files with 167 additions and 22 deletions.
28 changes: 26 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@
{
"instanceof": "RegExp"
},
{
"instanceof": "Function"
},
{
"type": "boolean"
}
Expand Down
4 changes: 4 additions & 0 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ function shouldUseModulesPlugins(modules, resourcePath) {
return modules.auto.test(resourcePath);
}

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

return true;
}

Expand Down
91 changes: 75 additions & 16 deletions test/__snapshots__/modules-option.test.js.snap
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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

0 comments on commit 0902353

Please sign in to comment.