Skip to content

Commit 0f95841

Browse files
authored
feat: add fallback if custom getLocalIdent returns null (#1193)
1 parent 2f1573f commit 0f95841

File tree

7 files changed

+108
-6
lines changed

7 files changed

+108
-6
lines changed

README.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -848,6 +848,8 @@ Default: `undefined`
848848

849849
Allows to specify a function to generate the classname.
850850
By default we use built-in function to generate a classname.
851+
If the custom function returns `null` or `undefined`, we fallback to the
852+
built-in function to generate the classname.
851853

852854
**webpack.config.js**
853855

@@ -1245,7 +1247,7 @@ module.exports = {
12451247

12461248
### Separating `Interoperable CSS`-only and `CSS Module` features
12471249

1248-
The following setup is an example of allowing `Interoperable CSS` features only (such as `:import` and `:export`) without using further `CSS Module` functionality by setting `compileType` option for all files that do not match `*.module.scss` naming convention. This is for reference as having `ICSS` features applied to all files was default `css-loader` behavior before v4.
1250+
The following setup is an example of allowing `Interoperable CSS` features only (such as `:import` and `:export`) without using further `CSS Module` functionality by setting `compileType` option for all files that do not match `*.module.scss` naming convention. This is for reference as having `ICSS` features applied to all files was default `css-loader` behavior before v4.
12491251
Meanwhile all files matching `*.module.scss` are treated as `CSS Modules` in this example.
12501252

12511253
An example case is assumed where a project requires canvas drawing variables to be synchronized with CSS - canvas drawing uses the same color (set by color name in JavaScript) as HTML background (set by class name in CSS).

src/utils.js

+26-5
Original file line numberDiff line numberDiff line change
@@ -281,11 +281,32 @@ function getModulesPlugins(options, loaderContext) {
281281
extractImports(),
282282
modulesScope({
283283
generateScopedName(exportName) {
284-
return getLocalIdent(loaderContext, localIdentName, exportName, {
285-
context: localIdentContext,
286-
hashPrefix: localIdentHashPrefix,
287-
regExp: localIdentRegExp,
288-
});
284+
let localIdent = getLocalIdent(
285+
loaderContext,
286+
localIdentName,
287+
exportName,
288+
{
289+
context: localIdentContext,
290+
hashPrefix: localIdentHashPrefix,
291+
regExp: localIdentRegExp,
292+
}
293+
);
294+
295+
// A null/undefined value signals that we should invoke the default
296+
// getLocalIdent method.
297+
if (localIdent == null) {
298+
localIdent = defaultGetLocalIdent(
299+
loaderContext,
300+
localIdentName,
301+
exportName,
302+
{
303+
context: localIdentContext,
304+
hashPrefix: localIdentHashPrefix,
305+
regExp: localIdentRegExp,
306+
}
307+
);
308+
}
309+
return localIdent;
289310
},
290311
exportGlobals: options.modules.exportGlobals,
291312
}),

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

+43
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,49 @@ exports[`"modules" option issue #1063: result 1`] = `
487487

488488
exports[`"modules" option issue #1063: warnings 1`] = `Array []`;
489489

490+
exports[`"modules" option issue #1191 - fallback to default getLocalIdent: errors 1`] = `Array []`;
491+
492+
exports[`"modules" option issue #1191 - fallback to default getLocalIdent: module 1`] = `
493+
"// Imports
494+
import ___CSS_LOADER_API_IMPORT___ from \\"../../../../src/runtime/api.js\\";
495+
var ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(false);
496+
// Module
497+
___CSS_LOADER_EXPORT___.push([module.id, \\".some-class {\\\\n color: red;\\\\n}\\\\n\\", \\"\\"]);
498+
// Exports
499+
___CSS_LOADER_EXPORT___.locals = {
500+
\\"some-class\\": \\"some-class\\"
501+
};
502+
export default ___CSS_LOADER_EXPORT___;
503+
"
504+
`;
505+
506+
exports[`"modules" option issue #1191 - fallback to default getLocalIdent: result 1`] = `
507+
Object {
508+
"css1": Array [
509+
Array [
510+
"./modules/issue-1191/issue-1191.css",
511+
".some-class {
512+
color: red;
513+
}
514+
",
515+
"",
516+
],
517+
],
518+
"css2": Array [
519+
Array [
520+
"./modules/issue-1191/issue-1191-custom.css",
521+
".custom-some-class {
522+
color: red;
523+
}
524+
",
525+
"",
526+
],
527+
],
528+
}
529+
`;
530+
531+
exports[`"modules" option issue #1191 - fallback to default getLocalIdent: warnings 1`] = `Array []`;
532+
490533
exports[`"modules" option should avoid unnecessary "require": errors 1`] = `Array []`;
491534

492535
exports[`"modules" option should avoid unnecessary "require": module 1`] = `
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.some-class {
2+
color: red;
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.some-class {
2+
color: red;
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import css1 from './issue-1191.css';
2+
import css2 from './issue-1191-custom.css';
3+
4+
const wrapper = { css1, css2 }
5+
6+
__export__ = wrapper;
7+
8+
export default wrapper;

test/modules-option.test.js

+22
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,28 @@ describe('"modules" option', () => {
657657
expect(getErrors(stats)).toMatchSnapshot('errors');
658658
});
659659

660+
it('issue #1191 - fallback to default getLocalIdent', async () => {
661+
const compiler = getCompiler('./modules/issue-1191/issue-1191.js', {
662+
modules: {
663+
getLocalIdent: (ctx, localIdentName, localName) =>
664+
ctx.resourcePath.includes('custom') ? `custom-${localName}` : null,
665+
localIdentName: '[local]',
666+
},
667+
});
668+
const stats = await compile(compiler);
669+
670+
expect(
671+
getModuleSource('./modules/issue-1191/issue-1191.css', stats)
672+
).toMatchSnapshot('module');
673+
674+
expect(getExecutedCode('main.bundle.js', compiler, stats)).toMatchSnapshot(
675+
'result'
676+
);
677+
678+
expect(getWarnings(stats)).toMatchSnapshot('warnings');
679+
expect(getErrors(stats)).toMatchSnapshot('errors');
680+
});
681+
660682
it('should work with the `exportGlobals` option (the `mode` option is `global`)', async () => {
661683
const compiler = getCompiler(
662684
'./modules/exportGlobals-global/exportGlobals.js',

0 commit comments

Comments
 (0)