Skip to content

Commit d6c31a1

Browse files
fix: automatically rename class default to _default when named export is enabled (#1590)
1 parent b162e25 commit d6c31a1

File tree

6 files changed

+123
-2
lines changed

6 files changed

+123
-2
lines changed

README.md

+7-1
Original file line numberDiff line numberDiff line change
@@ -1156,7 +1156,7 @@ Enables/disables ES modules named export for locals.
11561156

11571157
> **Warning**
11581158
>
1159-
> It is not allowed to use the `default` reserved word in css classes.
1159+
> Because it is not allowed to use the `default` class in CSS when the `namedExport` is `true` (since ECMA modules have a reserved keyword `default` for default export), it will be automatically renamed to the `_default` class.
11601160
11611161
**styles.css**
11621162

@@ -1167,6 +1167,9 @@ Enables/disables ES modules named export for locals.
11671167
.bar {
11681168
color: blue;
11691169
}
1170+
.default {
1171+
color: green;
1172+
}
11701173
```
11711174

11721175
**index.js**
@@ -1179,6 +1182,9 @@ console.log(styles["foo-baz"], styles.bar);
11791182

11801183
// If using `exportLocalsConvention: "camel-case-only"`:
11811184
console.log(styles.fooBaz, styles.bar);
1185+
1186+
// For the `default` classname
1187+
console.log(styles["_default"]);
11821188
```
11831189

11841190
You can enable a ES module named export using:

src/utils.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -1184,12 +1184,16 @@ function getExportCode(
11841184
? new Set(names)
11851185
: new Set([names]);
11861186

1187-
for (const name of normalizedNames) {
1187+
for (let name of normalizedNames) {
11881188
const serializedValue = isTemplateLiteralSupported
11891189
? convertToTemplateLiteral(value)
11901190
: JSON.stringify(value);
11911191

11921192
if (options.modules.namedExport) {
1193+
if (name === "default") {
1194+
name = `_${name}`;
1195+
}
1196+
11931197
if (!validIdentifier.test(name) || keywords.has(name)) {
11941198
identifierId += 1;
11951199

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

+68
Original file line numberDiff line numberDiff line change
@@ -12317,6 +12317,74 @@ exports[`"modules" option should work with \`@scope\` at-rule: result 1`] = `
1231712317

1231812318
exports[`"modules" option should work with \`@scope\` at-rule: warnings 1`] = `[]`;
1231912319

12320+
exports[`"modules" option should work with \`default\` class and with named export: errors 1`] = `[]`;
12321+
12322+
exports[`"modules" option should work with \`default\` class and with named export: module 1`] = `
12323+
"// Imports
12324+
import ___CSS_LOADER_API_NO_SOURCEMAP_IMPORT___ from "../../../../src/runtime/noSourceMaps.js";
12325+
import ___CSS_LOADER_API_IMPORT___ from "../../../../src/runtime/api.js";
12326+
var ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_NO_SOURCEMAP_IMPORT___);
12327+
// Module
12328+
___CSS_LOADER_EXPORT___.push([module.id, \`.VP7CYSvMVRONwmJxbckO {
12329+
background: red
12330+
}
12331+
\`, ""]);
12332+
// Exports
12333+
export var _default = \`VP7CYSvMVRONwmJxbckO\`;
12334+
export default ___CSS_LOADER_EXPORT___;
12335+
"
12336+
`;
12337+
12338+
exports[`"modules" option should work with \`default\` class and with named export: result 1`] = `
12339+
[
12340+
[
12341+
"./modules/issue-1589/source.css",
12342+
".VP7CYSvMVRONwmJxbckO {
12343+
background: red
12344+
}
12345+
",
12346+
"",
12347+
],
12348+
]
12349+
`;
12350+
12351+
exports[`"modules" option should work with \`default\` class and with named export: warnings 1`] = `[]`;
12352+
12353+
exports[`"modules" option should work with \`default\` class and without named export: errors 1`] = `[]`;
12354+
12355+
exports[`"modules" option should work with \`default\` class and without named export: module 1`] = `
12356+
"// Imports
12357+
import ___CSS_LOADER_API_NO_SOURCEMAP_IMPORT___ from "../../../../src/runtime/noSourceMaps.js";
12358+
import ___CSS_LOADER_API_IMPORT___ from "../../../../src/runtime/api.js";
12359+
var ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_NO_SOURCEMAP_IMPORT___);
12360+
// Module
12361+
___CSS_LOADER_EXPORT___.push([module.id, \`.VP7CYSvMVRONwmJxbckO {
12362+
background: red
12363+
}
12364+
\`, ""]);
12365+
// Exports
12366+
___CSS_LOADER_EXPORT___.locals = {
12367+
"default": \`VP7CYSvMVRONwmJxbckO\`
12368+
};
12369+
export default ___CSS_LOADER_EXPORT___;
12370+
"
12371+
`;
12372+
12373+
exports[`"modules" option should work with \`default\` class and without named export: result 1`] = `
12374+
[
12375+
[
12376+
"./modules/issue-1589/source.css",
12377+
".VP7CYSvMVRONwmJxbckO {
12378+
background: red
12379+
}
12380+
",
12381+
"",
12382+
],
12383+
]
12384+
`;
12385+
12386+
exports[`"modules" option should work with \`default\` class and without named export: warnings 1`] = `[]`;
12387+
1232012388
exports[`"modules" option should work with CSS nesting: errors 1`] = `[]`;
1232112389

1232212390
exports[`"modules" option should work with CSS nesting: module 1`] = `
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.default {
2+
background: red
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import * as css from './source.css';
2+
3+
__export__ = css.default;
4+
5+
export default css;

test/modules-option.test.js

+35
Original file line numberDiff line numberDiff line change
@@ -2657,4 +2657,39 @@ describe('"modules" option', () => {
26572657
expect(getWarnings(stats)).toMatchSnapshot("warnings");
26582658
expect(getErrors(stats)).toMatchSnapshot("errors");
26592659
});
2660+
2661+
it("should work with `default` class and without named export", async () => {
2662+
const compiler = getCompiler("./modules/issue-1589/source.js", {
2663+
modules: {
2664+
exportLocalsConvention: "as-is",
2665+
namedExport: false,
2666+
},
2667+
});
2668+
const stats = await compile(compiler);
2669+
2670+
expect(
2671+
getModuleSource("./modules/issue-1589/source.css", stats),
2672+
).toMatchSnapshot("module");
2673+
expect(getExecutedCode("main.bundle.js", compiler, stats)).toMatchSnapshot(
2674+
"result",
2675+
);
2676+
expect(getWarnings(stats)).toMatchSnapshot("warnings");
2677+
expect(getErrors(stats)).toMatchSnapshot("errors");
2678+
});
2679+
2680+
it("should work with `default` class and with named export", async () => {
2681+
const compiler = getCompiler("./modules/issue-1589/source.js", {
2682+
modules: true,
2683+
});
2684+
const stats = await compile(compiler);
2685+
2686+
expect(
2687+
getModuleSource("./modules/issue-1589/source.css", stats),
2688+
).toMatchSnapshot("module");
2689+
expect(getExecutedCode("main.bundle.js", compiler, stats)).toMatchSnapshot(
2690+
"result",
2691+
);
2692+
expect(getWarnings(stats)).toMatchSnapshot("warnings");
2693+
expect(getErrors(stats)).toMatchSnapshot("errors");
2694+
});
26602695
});

0 commit comments

Comments
 (0)