Skip to content

Commit c673cf4

Browse files
feat: allow to determinate css modules using the modules.auto option (#1067)
1 parent 519e5f4 commit c673cf4

9 files changed

+309
-15
lines changed

README.md

+60
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,66 @@ module.exports = {
540540
};
541541
```
542542

543+
##### `auto`
544+
545+
Type: `Boolean|RegExp`
546+
Default: `'undefined'`
547+
548+
Allows auto enable css modules based on filename.
549+
550+
###### `Boolean`
551+
552+
Possible values:
553+
554+
- `true` - enable css modules for all files for which `/\.module\.\w+$/i.test(filename)` return true
555+
- `false` - disable css modules
556+
557+
**webpack.config.js**
558+
559+
```js
560+
module.exports = {
561+
module: {
562+
rules: [
563+
{
564+
test: /\.css$/i,
565+
loader: 'css-loader',
566+
options: {
567+
modules: {
568+
// All files for which /\.module\.\w+$/i.test(filename) return true
569+
auto: true,
570+
},
571+
},
572+
},
573+
],
574+
},
575+
};
576+
```
577+
578+
###### `RegExp`
579+
580+
Enable css modules for files based on filename and satisfying `/youRegExp/.test(filename)` regex.
581+
582+
**webpack.config.js**
583+
584+
```js
585+
module.exports = {
586+
module: {
587+
rules: [
588+
{
589+
test: /\.css$/i,
590+
loader: 'css-loader',
591+
options: {
592+
modules: {
593+
// All files for which /youRegExp/i.test(filename) return true
594+
auto: /youRegExp/i,
595+
},
596+
},
597+
},
598+
],
599+
},
600+
};
601+
```
602+
543603
##### `mode`
544604

545605
Type: `String|Function`

src/index.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
getModuleCode,
2121
getModulesPlugins,
2222
normalizeSourceMap,
23+
shouldUseModulesPlugins,
2324
} from './utils';
2425

2526
export default function loader(content, map, meta) {
@@ -34,7 +35,7 @@ export default function loader(content, map, meta) {
3435
const sourceMap = options.sourceMap || false;
3536
const plugins = [];
3637

37-
if (options.modules) {
38+
if (shouldUseModulesPlugins(options.modules, this.resourcePath)) {
3839
plugins.push(...getModulesPlugins(options, this));
3940
}
4041

src/options.json

+10
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,16 @@
3636
"type": "object",
3737
"additionalProperties": false,
3838
"properties": {
39+
"auto": {
40+
"anyOf": [
41+
{
42+
"type": "object"
43+
},
44+
{
45+
"type": "boolean"
46+
}
47+
]
48+
},
3949
"mode": {
4050
"anyOf": [
4151
{

src/utils.js

+25
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,30 @@ function getFilter(filter, resourcePath, defaultFilter = null) {
9696
};
9797
}
9898

99+
function shouldUseModulesPlugins(modules, resourcePath) {
100+
if (typeof modules === 'undefined') {
101+
return false;
102+
}
103+
104+
if (typeof modules === 'boolean') {
105+
return modules;
106+
}
107+
108+
if (typeof modules === 'string') {
109+
return true;
110+
}
111+
112+
if (typeof modules.auto === 'boolean') {
113+
return modules.auto ? /\.module\.\w+$/i.test(resourcePath) : false;
114+
}
115+
116+
if (modules.auto instanceof RegExp) {
117+
return modules.auto.test(resourcePath);
118+
}
119+
120+
return true;
121+
}
122+
99123
function getModulesPlugins(options, loaderContext) {
100124
let modulesOptions = {
101125
mode: 'local',
@@ -405,4 +429,5 @@ export {
405429
getImportCode,
406430
getModuleCode,
407431
getExportCode,
432+
shouldUseModulesPlugins,
408433
};

test/__snapshots__/modules-option.test.js.snap

+118
Original file line numberDiff line numberDiff line change
@@ -3148,6 +3148,124 @@ Array [
31483148
31493149
exports[`"modules" option should work when the "getLocalIdent" option returns "false": warnings 1`] = `Array []`;
31503150
3151+
exports[`"modules" option should work with a modules.auto equal "false": errors 1`] = `Array []`;
3152+
3153+
exports[`"modules" option should work with a modules.auto equal "false": module 1`] = `
3154+
"// Imports
3155+
var ___CSS_LOADER_API_IMPORT___ = require(\\"../../../../src/runtime/api.js\\");
3156+
exports = ___CSS_LOADER_API_IMPORT___(false);
3157+
// Module
3158+
exports.push([module.id, \\".relative {\\\\n color: red;\\\\n}\\\\n\\", \\"\\"]);
3159+
// Exports
3160+
module.exports = exports;
3161+
"
3162+
`;
3163+
3164+
exports[`"modules" option should work with a modules.auto equal "false": result 1`] = `
3165+
Array [
3166+
Array [
3167+
"./modules/mode/relative.module.css",
3168+
".relative {
3169+
color: red;
3170+
}
3171+
",
3172+
"",
3173+
],
3174+
]
3175+
`;
3176+
3177+
exports[`"modules" option should work with a modules.auto equal "false": warnings 1`] = `Array []`;
3178+
3179+
exports[`"modules" option should work with a modules.auto equal "true": errors 1`] = `Array []`;
3180+
3181+
exports[`"modules" option should work with a modules.auto equal "true": module 1`] = `
3182+
"// Imports
3183+
var ___CSS_LOADER_API_IMPORT___ = require(\\"../../../../src/runtime/api.js\\");
3184+
exports = ___CSS_LOADER_API_IMPORT___(false);
3185+
// Module
3186+
exports.push([module.id, \\".y35Nud52-ZFXmqL6AWueX {\\\\n color: red;\\\\n}\\\\n\\", \\"\\"]);
3187+
// Exports
3188+
exports.locals = {
3189+
\\"relative\\": \\"y35Nud52-ZFXmqL6AWueX\\"
3190+
};
3191+
module.exports = exports;
3192+
"
3193+
`;
3194+
3195+
exports[`"modules" option should work with a modules.auto equal "true": result 1`] = `
3196+
Array [
3197+
Array [
3198+
"./modules/mode/relative.module.css",
3199+
".y35Nud52-ZFXmqL6AWueX {
3200+
color: red;
3201+
}
3202+
",
3203+
"",
3204+
],
3205+
]
3206+
`;
3207+
3208+
exports[`"modules" option should work with a modules.auto equal "true": warnings 1`] = `Array []`;
3209+
3210+
exports[`"modules" option should work with a modules.auto returns "false": errors 1`] = `Array []`;
3211+
3212+
exports[`"modules" option should work with a modules.auto returns "false": module 1`] = `
3213+
"// Imports
3214+
var ___CSS_LOADER_API_IMPORT___ = require(\\"../../../../src/runtime/api.js\\");
3215+
exports = ___CSS_LOADER_API_IMPORT___(false);
3216+
// Module
3217+
exports.push([module.id, \\".relative {\\\\n color: red;\\\\n}\\\\n\\", \\"\\"]);
3218+
// Exports
3219+
module.exports = exports;
3220+
"
3221+
`;
3222+
3223+
exports[`"modules" option should work with a modules.auto returns "false": result 1`] = `
3224+
Array [
3225+
Array [
3226+
"./modules/mode/relative.module.css",
3227+
".relative {
3228+
color: red;
3229+
}
3230+
",
3231+
"",
3232+
],
3233+
]
3234+
`;
3235+
3236+
exports[`"modules" option should work with a modules.auto returns "false": warnings 1`] = `Array []`;
3237+
3238+
exports[`"modules" option should work with a modules.auto returns "true": errors 1`] = `Array []`;
3239+
3240+
exports[`"modules" option should work with a modules.auto returns "true": module 1`] = `
3241+
"// Imports
3242+
var ___CSS_LOADER_API_IMPORT___ = require(\\"../../../../src/runtime/api.js\\");
3243+
exports = ___CSS_LOADER_API_IMPORT___(false);
3244+
// Module
3245+
exports.push([module.id, \\".y35Nud52-ZFXmqL6AWueX {\\\\n color: red;\\\\n}\\\\n\\", \\"\\"]);
3246+
// Exports
3247+
exports.locals = {
3248+
\\"relative\\": \\"y35Nud52-ZFXmqL6AWueX\\"
3249+
};
3250+
module.exports = exports;
3251+
"
3252+
`;
3253+
3254+
exports[`"modules" option should work with a modules.auto returns "true": result 1`] = `
3255+
Array [
3256+
Array [
3257+
"./modules/mode/relative.module.css",
3258+
".y35Nud52-ZFXmqL6AWueX {
3259+
color: red;
3260+
}
3261+
",
3262+
"",
3263+
],
3264+
]
3265+
`;
3266+
3267+
exports[`"modules" option should work with a modules.auto returns "true": warnings 1`] = `Array []`;
3268+
31513269
exports[`"modules" option should work with case \`animation\` (\`modules\` value is \`false)\`: errors 1`] = `Array []`;
31523270
31533271
exports[`"modules" option should work with case \`animation\` (\`modules\` value is \`false)\`: module 1`] = `

test/__snapshots__/validate-options.test.js.snap

+14-14
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ exports[`validate options should throw an error on the "modules" option with "{"
5656
exports[`validate options should throw an error on the "modules" option with "{"getLocalIdent":[]}" value 1`] = `
5757
"Invalid options object. CSS Loader has been initialized using an options object that does not match the API schema.
5858
- options.modules should be one of these:
59-
boolean | \\"local\\" | \\"global\\" | \\"pure\\" | object { mode?, exportGlobals?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? }
59+
boolean | \\"local\\" | \\"global\\" | \\"pure\\" | object { auto?, mode?, exportGlobals?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? }
6060
-> Enables/Disables CSS Modules and their configuration (https://github.com/webpack-contrib/css-loader#modules).
6161
Details:
6262
* options.modules.getLocalIdent should be one of these:
@@ -79,7 +79,7 @@ exports[`validate options should throw an error on the "modules" option with "{"
7979
exports[`validate options should throw an error on the "modules" option with "{"localIdentRegExp":true}" value 1`] = `
8080
"Invalid options object. CSS Loader has been initialized using an options object that does not match the API schema.
8181
- options.modules should be one of these:
82-
boolean | \\"local\\" | \\"global\\" | \\"pure\\" | object { mode?, exportGlobals?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? }
82+
boolean | \\"local\\" | \\"global\\" | \\"pure\\" | object { auto?, mode?, exportGlobals?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? }
8383
-> Enables/Disables CSS Modules and their configuration (https://github.com/webpack-contrib/css-loader#modules).
8484
Details:
8585
* options.modules.localIdentRegExp should be one of these:
@@ -92,7 +92,7 @@ exports[`validate options should throw an error on the "modules" option with "{"
9292
exports[`validate options should throw an error on the "modules" option with "{"mode":"globals"}" value 1`] = `
9393
"Invalid options object. CSS Loader has been initialized using an options object that does not match the API schema.
9494
- options.modules should be one of these:
95-
boolean | \\"local\\" | \\"global\\" | \\"pure\\" | object { mode?, exportGlobals?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? }
95+
boolean | \\"local\\" | \\"global\\" | \\"pure\\" | object { auto?, mode?, exportGlobals?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? }
9696
-> Enables/Disables CSS Modules and their configuration (https://github.com/webpack-contrib/css-loader#modules).
9797
Details:
9898
* options.modules.mode should be one of these:
@@ -106,7 +106,7 @@ exports[`validate options should throw an error on the "modules" option with "{"
106106
exports[`validate options should throw an error on the "modules" option with "{"mode":"locals"}" value 1`] = `
107107
"Invalid options object. CSS Loader has been initialized using an options object that does not match the API schema.
108108
- options.modules should be one of these:
109-
boolean | \\"local\\" | \\"global\\" | \\"pure\\" | object { mode?, exportGlobals?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? }
109+
boolean | \\"local\\" | \\"global\\" | \\"pure\\" | object { auto?, mode?, exportGlobals?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? }
110110
-> Enables/Disables CSS Modules and their configuration (https://github.com/webpack-contrib/css-loader#modules).
111111
Details:
112112
* options.modules.mode should be one of these:
@@ -120,7 +120,7 @@ exports[`validate options should throw an error on the "modules" option with "{"
120120
exports[`validate options should throw an error on the "modules" option with "{"mode":"pures"}" value 1`] = `
121121
"Invalid options object. CSS Loader has been initialized using an options object that does not match the API schema.
122122
- options.modules should be one of these:
123-
boolean | \\"local\\" | \\"global\\" | \\"pure\\" | object { mode?, exportGlobals?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? }
123+
boolean | \\"local\\" | \\"global\\" | \\"pure\\" | object { auto?, mode?, exportGlobals?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? }
124124
-> Enables/Disables CSS Modules and their configuration (https://github.com/webpack-contrib/css-loader#modules).
125125
Details:
126126
* options.modules.mode should be one of these:
@@ -134,7 +134,7 @@ exports[`validate options should throw an error on the "modules" option with "{"
134134
exports[`validate options should throw an error on the "modules" option with "{"mode":true}" value 1`] = `
135135
"Invalid options object. CSS Loader has been initialized using an options object that does not match the API schema.
136136
- options.modules should be one of these:
137-
boolean | \\"local\\" | \\"global\\" | \\"pure\\" | object { mode?, exportGlobals?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? }
137+
boolean | \\"local\\" | \\"global\\" | \\"pure\\" | object { auto?, mode?, exportGlobals?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? }
138138
-> Enables/Disables CSS Modules and their configuration (https://github.com/webpack-contrib/css-loader#modules).
139139
Details:
140140
* options.modules.mode should be one of these:
@@ -148,53 +148,53 @@ exports[`validate options should throw an error on the "modules" option with "{"
148148
exports[`validate options should throw an error on the "modules" option with "globals" value 1`] = `
149149
"Invalid options object. CSS Loader has been initialized using an options object that does not match the API schema.
150150
- options.modules should be one of these:
151-
boolean | \\"local\\" | \\"global\\" | \\"pure\\" | object { mode?, exportGlobals?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? }
151+
boolean | \\"local\\" | \\"global\\" | \\"pure\\" | object { auto?, mode?, exportGlobals?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? }
152152
-> Enables/Disables CSS Modules and their configuration (https://github.com/webpack-contrib/css-loader#modules).
153153
Details:
154154
* options.modules should be a boolean.
155155
* options.modules should be one of these:
156156
\\"local\\" | \\"global\\" | \\"pure\\"
157157
* options.modules should be an object:
158-
object { mode?, exportGlobals?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? }"
158+
object { auto?, mode?, exportGlobals?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? }"
159159
`;
160160
161161
exports[`validate options should throw an error on the "modules" option with "locals" value 1`] = `
162162
"Invalid options object. CSS Loader has been initialized using an options object that does not match the API schema.
163163
- options.modules should be one of these:
164-
boolean | \\"local\\" | \\"global\\" | \\"pure\\" | object { mode?, exportGlobals?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? }
164+
boolean | \\"local\\" | \\"global\\" | \\"pure\\" | object { auto?, mode?, exportGlobals?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? }
165165
-> Enables/Disables CSS Modules and their configuration (https://github.com/webpack-contrib/css-loader#modules).
166166
Details:
167167
* options.modules should be a boolean.
168168
* options.modules should be one of these:
169169
\\"local\\" | \\"global\\" | \\"pure\\"
170170
* options.modules should be an object:
171-
object { mode?, exportGlobals?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? }"
171+
object { auto?, mode?, exportGlobals?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? }"
172172
`;
173173
174174
exports[`validate options should throw an error on the "modules" option with "pures" value 1`] = `
175175
"Invalid options object. CSS Loader has been initialized using an options object that does not match the API schema.
176176
- options.modules should be one of these:
177-
boolean | \\"local\\" | \\"global\\" | \\"pure\\" | object { mode?, exportGlobals?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? }
177+
boolean | \\"local\\" | \\"global\\" | \\"pure\\" | object { auto?, mode?, exportGlobals?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? }
178178
-> Enables/Disables CSS Modules and their configuration (https://github.com/webpack-contrib/css-loader#modules).
179179
Details:
180180
* options.modules should be a boolean.
181181
* options.modules should be one of these:
182182
\\"local\\" | \\"global\\" | \\"pure\\"
183183
* options.modules should be an object:
184-
object { mode?, exportGlobals?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? }"
184+
object { auto?, mode?, exportGlobals?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? }"
185185
`;
186186
187187
exports[`validate options should throw an error on the "modules" option with "true" value 1`] = `
188188
"Invalid options object. CSS Loader has been initialized using an options object that does not match the API schema.
189189
- options.modules should be one of these:
190-
boolean | \\"local\\" | \\"global\\" | \\"pure\\" | object { mode?, exportGlobals?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? }
190+
boolean | \\"local\\" | \\"global\\" | \\"pure\\" | object { auto?, mode?, exportGlobals?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? }
191191
-> Enables/Disables CSS Modules and their configuration (https://github.com/webpack-contrib/css-loader#modules).
192192
Details:
193193
* options.modules should be a boolean.
194194
* options.modules should be one of these:
195195
\\"local\\" | \\"global\\" | \\"pure\\"
196196
* options.modules should be an object:
197-
object { mode?, exportGlobals?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? }"
197+
object { auto?, mode?, exportGlobals?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? }"
198198
`;
199199
200200
exports[`validate options should throw an error on the "onlyLocals" option with "true" value 1`] = `

test/fixtures/modules/mode/modules.js

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import relative from './relative.module.css';
2+
3+
__export__ = relative;
4+
5+
export default relative;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.relative {
2+
color: red;
3+
}

0 commit comments

Comments
 (0)