Skip to content

Commit f96a110

Browse files
feat: namedExports works fine with any exportLocalsConvention value
1 parent 9852aa6 commit f96a110

File tree

5 files changed

+4279
-3992
lines changed

5 files changed

+4279
-3992
lines changed

README.md

+2-7
Original file line numberDiff line numberDiff line change
@@ -1144,7 +1144,7 @@ Enables/disables ES modules named export for locals.
11441144

11451145
> **Warning**
11461146
>
1147-
> It is not allowed to use JavaScript reserved words in css class names unless `exportLocalsConvention` is `"as-is"`.
1147+
> It is not allowed to use the `default` reserved word in css classes.
11481148
11491149
**styles.css**
11501150

@@ -1247,12 +1247,7 @@ Default: Depends on the value of the `modules.namedExport` option, if `true` - `
12471247
>
12481248
> Names of locals are converted to camelcase when the named export is `false`, i.e. the `exportLocalsConvention` option has
12491249
> `camelCaseOnly` value by default. You can set this back to any other valid option but selectors
1250-
> which are not valid JavaScript identifiers may run into problems which do not implement the entire
1251-
> modules specification.
1252-
1253-
> **Warning**
1254-
>
1255-
> **You need to disable `modules.namedExport` if you want to use `'camel-case'` or `'dashes'` value.**
1250+
> which are not valid JavaScript identifiers may run into problems which do not implement the entire modules specification.
12561251
12571252
Style of exported class names.
12581253

src/utils.js

+74-28
Original file line numberDiff line numberDiff line change
@@ -550,16 +550,12 @@ function getModulesOptions(rawOptions, esModule, exportType, loaderContext) {
550550
namedExport,
551551
};
552552

553-
let exportLocalsConventionType;
554-
555553
if (typeof modulesOptions.exportLocalsConvention === "string") {
556-
exportLocalsConventionType = modulesOptions.exportLocalsConvention;
554+
// eslint-disable-next-line no-shadow
555+
const { exportLocalsConvention } = modulesOptions;
557556

558-
modulesOptions.useExportsAs =
559-
exportLocalsConventionType === "as-is" ||
560-
exportLocalsConventionType === "asIs";
561557
modulesOptions.exportLocalsConvention = (name) => {
562-
switch (exportLocalsConventionType) {
558+
switch (exportLocalsConvention) {
563559
case "camel-case":
564560
case "camelCase": {
565561
return [name, camelCase(name)];
@@ -640,26 +636,10 @@ function getModulesOptions(rawOptions, esModule, exportType, loaderContext) {
640636
}
641637
}
642638

643-
if (modulesOptions.namedExport === true) {
644-
if (esModule === false) {
645-
throw new Error(
646-
"The 'modules.namedExport' option requires the 'esModule' option to be enabled",
647-
);
648-
}
649-
650-
/* if (
651-
typeof exportLocalsConventionType === "string" &&
652-
exportLocalsConventionType !== "asIs" &&
653-
exportLocalsConventionType !== "as-is" &&
654-
exportLocalsConventionType !== "camelCaseOnly" &&
655-
exportLocalsConventionType !== "camel-case-only" &&
656-
exportLocalsConventionType !== "dashesOnly" &&
657-
exportLocalsConventionType !== "dashes-only"
658-
) {
659-
throw new Error(
660-
'The "modules.namedExport" option requires the "modules.exportLocalsConvention" option to be "as-is", "camel-case-only" or "dashes-only"',
661-
);
662-
}*/
639+
if (modulesOptions.namedExport === true && esModule === false) {
640+
throw new Error(
641+
"The 'modules.namedExport' option requires the 'esModule' option to be enabled",
642+
);
663643
}
664644

665645
return modulesOptions;
@@ -1123,6 +1103,69 @@ function dashesCamelCase(str) {
11231103
);
11241104
}
11251105

1106+
const validIdentifier = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/u;
1107+
const keywords = new Set([
1108+
"abstract",
1109+
"boolean",
1110+
"break",
1111+
"byte",
1112+
"case",
1113+
"catch",
1114+
"char",
1115+
"class",
1116+
"const",
1117+
"continue",
1118+
"debugger",
1119+
"default",
1120+
"delete",
1121+
"do",
1122+
"double",
1123+
"else",
1124+
"enum",
1125+
"export",
1126+
"extends",
1127+
"false",
1128+
"final",
1129+
"finally",
1130+
"float",
1131+
"for",
1132+
"function",
1133+
"goto",
1134+
"if",
1135+
"implements",
1136+
"import",
1137+
"in",
1138+
"instanceof",
1139+
"int",
1140+
"interface",
1141+
"long",
1142+
"native",
1143+
"new",
1144+
"null",
1145+
"package",
1146+
"private",
1147+
"protected",
1148+
"public",
1149+
"return",
1150+
"short",
1151+
"static",
1152+
"super",
1153+
"switch",
1154+
"synchronized",
1155+
"this",
1156+
"throw",
1157+
"throws",
1158+
"transient",
1159+
"true",
1160+
"try",
1161+
"typeof",
1162+
"var",
1163+
"void",
1164+
"volatile",
1165+
"while",
1166+
"with",
1167+
]);
1168+
11261169
function getExportCode(
11271170
exports,
11281171
replacements,
@@ -1145,10 +1188,13 @@ function getExportCode(
11451188
const serializedValue = isTemplateLiteralSupported
11461189
? convertToTemplateLiteral(value)
11471190
: JSON.stringify(value);
1191+
11481192
if (options.modules.namedExport) {
1149-
if (options.modules.useExportsAs) {
1193+
if (!validIdentifier.test(name) || keywords.has(name)) {
11501194
identifierId += 1;
1195+
11511196
const id = `_${identifierId.toString(16)}`;
1197+
11521198
localsCode += `var ${id} = ${serializedValue};\n`;
11531199
localsCode += `export { ${id} as ${JSON.stringify(name)} };\n`;
11541200
} else {

0 commit comments

Comments
 (0)