Skip to content

Commit 40e1668

Browse files
committedApr 4, 2024
feat: added dashed variants for the exportLocalsConvention options
1 parent 5d4b1bf commit 40e1668

7 files changed

+68
-55
lines changed
 

‎README.md

+21-21
Original file line numberDiff line numberDiff line change
@@ -320,11 +320,11 @@ type modules =
320320
namedExport: boolean;
321321
exportGlobals: boolean;
322322
exportLocalsConvention:
323-
| "asIs"
324-
| "camelCase"
325-
| "camelCaseOnly"
323+
| "as-is"
324+
| "camel-case"
325+
| "camel-case-only"
326326
| "dashes"
327-
| "dashesOnly"
327+
| "dashes-only"
328328
| ((name: string) => string);
329329
exportOnlyLocals: boolean;
330330
};
@@ -602,7 +602,7 @@ module.exports = {
602602
localIdentContext: path.resolve(__dirname, "src"),
603603
localIdentHashSalt: "my-custom-hash",
604604
namedExport: true,
605-
exportLocalsConvention: "camelCase",
605+
exportLocalsConvention: "as-is",
606606
exportOnlyLocals: false,
607607
},
608608
},
@@ -1152,7 +1152,7 @@ Enables/disables ES modules named export for locals.
11521152
> **Warning**
11531153
>
11541154
> It is not allowed to use JavaScript reserved words in css class names unless
1155-
> `exportLocalsConvention` is `"asIs"`.
1155+
> `exportLocalsConvention` is `"as-is"`.
11561156
11571157
**styles.css**
11581158

@@ -1171,7 +1171,7 @@ Enables/disables ES modules named export for locals.
11711171
import * as styles from "./styles.css";
11721172

11731173
console.log(styles.fooBaz, styles.bar);
1174-
// or if using `exportLocalsConvention: "asIs"`:
1174+
// or if using `exportLocalsConvention: "as-is"`:
11751175
console.log(styles["foo-baz"], styles.bar);
11761176
```
11771177

@@ -1239,29 +1239,29 @@ Type:
12391239

12401240
```ts
12411241
type exportLocalsConvention =
1242-
| "asIs"
1243-
| "camelCase"
1244-
| "camelCaseOnly"
1242+
| "as-is"
1243+
| "camel-case"
1244+
| "camel-case-only"
12451245
| "dashes"
1246-
| "dashesOnly"
1246+
| "dashes-only"
12471247
| ((name: string) => string);
12481248
```
12491249

1250-
Default: based on the `modules.namedExport` option value, if `true` - `camelCaseOnly`, otherwise `asIs`
1250+
Default: based on the `modules.namedExport` option value, if `true` - `camelCaseOnly`, otherwise `as-is`
12511251

12521252
Style of exported class names.
12531253

12541254
###### `string`
12551255

1256-
By default, the exported JSON keys mirror the class names (i.e `asIs` value).
1256+
By default, the exported JSON keys mirror the class names (i.e `as-is` value).
12571257

1258-
| Name | Type | Description |
1259-
| :-------------------: | :------: | :----------------------------------------------------------------------------------------------- |
1260-
| **`'asIs'`** | `string` | Class names will be exported as is. |
1261-
| **`'camelCase'`** | `string` | Class names will be camelized, the original class name will not to be removed from the locals |
1262-
| **`'camelCaseOnly'`** | `string` | Class names will be camelized, the original class name will be removed from the locals |
1263-
| **`'dashes'`** | `string` | Only dashes in class names will be camelized |
1264-
| **`'dashesOnly'`** | `string` | Dashes in class names will be camelized, the original class name will be removed from the locals |
1258+
| Name | Type | Description |
1259+
| :---------------------: | :------: | :----------------------------------------------------------------------------------------------- |
1260+
| **`'as-is'`** | `string` | Class names will be exported as is. |
1261+
| **`'camel-case'`** | `string` | Class names will be camelized, the original class name will not to be removed from the locals |
1262+
| **`'camel-case-only'`** | `string` | Class names will be camelized, the original class name will be removed from the locals |
1263+
| **`'dashes'`** | `string` | Only dashes in class names will be camelized |
1264+
| **`'dashes-only'`** | `string` | Dashes in class names will be camelized, the original class name will be removed from the locals |
12651265

12661266
**file.css**
12671267

@@ -1287,7 +1287,7 @@ module.exports = {
12871287
loader: "css-loader",
12881288
options: {
12891289
modules: {
1290-
exportLocalsConvention: "camelCase",
1290+
exportLocalsConvention: "camel-case",
12911291
},
12921292
},
12931293
},

‎src/options.json

+5-1
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,14 @@
154154
{
155155
"enum": [
156156
"asIs",
157+
"as-is",
157158
"camelCase",
159+
"camel-case",
158160
"camelCaseOnly",
161+
"camel-case-only",
159162
"dashes",
160-
"dashesOnly"
163+
"dashesOnly",
164+
"dashes-only"
161165
]
162166
},
163167
{

‎src/utils.js

+14-5
Original file line numberDiff line numberDiff line change
@@ -527,8 +527,8 @@ function getModulesOptions(rawOptions, esModule, exportType, loaderContext) {
527527
typeof rawModulesOptions.exportLocalsConvention !== "undefined"
528528
? rawModulesOptions.exportLocalsConvention
529529
: namedExport
530-
? "asIs"
531-
: "camelCaseOnly";
530+
? "as-is"
531+
: "camel-case-only";
532532
const modulesOptions = {
533533
auto,
534534
mode: "local",
@@ -555,21 +555,27 @@ function getModulesOptions(rawOptions, esModule, exportType, loaderContext) {
555555
if (typeof modulesOptions.exportLocalsConvention === "string") {
556556
exportLocalsConventionType = modulesOptions.exportLocalsConvention;
557557

558-
modulesOptions.useExportsAs = exportLocalsConventionType === "asIs";
558+
modulesOptions.useExportsAs =
559+
exportLocalsConventionType === "as-is" ||
560+
exportLocalsConventionType === "asIs";
559561
modulesOptions.exportLocalsConvention = (name) => {
560562
switch (exportLocalsConventionType) {
563+
case "camel-case":
561564
case "camelCase": {
562565
return [name, camelCase(name)];
563566
}
567+
case "camel-case-only":
564568
case "camelCaseOnly": {
565569
return camelCase(name);
566570
}
567571
case "dashes": {
568572
return [name, dashesCamelCase(name)];
569573
}
574+
case "dashes-only":
570575
case "dashesOnly": {
571576
return dashesCamelCase(name);
572577
}
578+
case "as-is":
573579
case "asIs":
574580
default:
575581
return name;
@@ -644,11 +650,14 @@ function getModulesOptions(rawOptions, esModule, exportType, loaderContext) {
644650
if (
645651
typeof exportLocalsConventionType === "string" &&
646652
exportLocalsConventionType !== "asIs" &&
653+
exportLocalsConventionType !== "as-is" &&
647654
exportLocalsConventionType !== "camelCaseOnly" &&
648-
exportLocalsConventionType !== "dashesOnly"
655+
exportLocalsConventionType !== "camel-case-only" &&
656+
exportLocalsConventionType !== "dashesOnly" &&
657+
exportLocalsConventionType !== "dashes-only"
649658
) {
650659
throw new Error(
651-
'The "modules.namedExport" option requires the "modules.exportLocalsConvention" option to be "asIs", "camelCaseOnly" or "dashesOnly"',
660+
'The "modules.namedExport" option requires the "modules.exportLocalsConvention" option to be "as-is", "camel-case-only" or "dashes-only"',
652661
);
653662
}
654663
}

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

+20-22
Original file line numberDiff line numberDiff line change
@@ -2552,7 +2552,7 @@ exports[`"modules" option should throw an error when class has unsupported name
25522552
exports[`"modules" option should throw an error when the "namedExport" is enabled and the "exportLocalsConvention" options has not "camelCaseOnly" value: errors 1`] = `
25532553
[
25542554
"ModuleBuildError: Module build failed (from \`replaced original path\`):
2555-
Error: The "modules.namedExport" option requires the "modules.exportLocalsConvention" option to be "asIs", "camelCaseOnly" or "dashesOnly"",
2555+
Error: The "modules.namedExport" option requires the "modules.exportLocalsConvention" option to be "as-is", "camel-case-only" or "dashes-only"",
25562556
]
25572557
`;
25582558

@@ -2579,7 +2579,7 @@ exports[`"modules" option should throw error when the "exportLocalsConvention" f
25792579
exports[`"modules" option should throw error with composes when the "namedExport" is enabled and "exportLocalsConvention" options has invalid value: errors 1`] = `
25802580
[
25812581
"ModuleBuildError: Module build failed (from \`replaced original path\`):
2582-
Error: The "modules.namedExport" option requires the "modules.exportLocalsConvention" option to be "asIs", "camelCaseOnly" or "dashesOnly"",
2582+
Error: The "modules.namedExport" option requires the "modules.exportLocalsConvention" option to be "as-is", "camel-case-only" or "dashes-only"",
25832583
]
25842584
`;
25852585

@@ -6454,9 +6454,9 @@ a {
64546454

64556455
exports[`"modules" option should work and respect the "localConvention" option with the "asIs" value: warnings 1`] = `[]`;
64566456

6457-
exports[`"modules" option should work and respect the "localConvention" option with the "camelCase" value: errors 1`] = `[]`;
6457+
exports[`"modules" option should work and respect the "localConvention" option with the "camel-case-only" value: errors 1`] = `[]`;
64586458

6459-
exports[`"modules" option should work and respect the "localConvention" option with the "camelCase" value: module 1`] = `
6459+
exports[`"modules" option should work and respect the "localConvention" option with the "camel-case-only" value: module 1`] = `
64606460
"// Imports
64616461
import ___CSS_LOADER_API_NO_SOURCEMAP_IMPORT___ from "../../../../src/runtime/noSourceMaps.js";
64626462
import ___CSS_LOADER_API_IMPORT___ from "../../../../src/runtime/api.js";
@@ -6483,23 +6483,17 @@ a {
64836483
}
64846484
\`, ""]);
64856485
// Exports
6486-
___CSS_LOADER_EXPORT___.locals = {
6487-
"foo": \`bar\`,
6488-
"my-btn-info_is-disabled": \`value\`,
6489-
"myBtnInfoIsDisabled": \`value\`,
6490-
"btn-info_is-disabled": \`rmc8ltu8P1VXaeqLNU6N\`,
6491-
"btnInfoIsDisabled": \`rmc8ltu8P1VXaeqLNU6N\`,
6492-
"btn--info_is-disabled_1": \`AooVHuvzAIGXWngdfslc\`,
6493-
"btnInfoIsDisabled1": \`AooVHuvzAIGXWngdfslc\`,
6494-
"simple": \`snmJCrfw3LVnrlx87XVC\`,
6495-
"foo_bar": \`vA4oeh0XymefKJVIJyg1\`,
6496-
"fooBar": \`vA4oeh0XymefKJVIJyg1\`
6497-
};
6486+
export var foo = \`bar\`;
6487+
export var myBtnInfoIsDisabled = \`value\`;
6488+
export var btnInfoIsDisabled = \`rmc8ltu8P1VXaeqLNU6N\`;
6489+
export var btnInfoIsDisabled1 = \`AooVHuvzAIGXWngdfslc\`;
6490+
export var simple = \`snmJCrfw3LVnrlx87XVC\`;
6491+
export var fooBar = \`vA4oeh0XymefKJVIJyg1\`;
64986492
export default ___CSS_LOADER_EXPORT___;
64996493
"
65006494
`;
65016495

6502-
exports[`"modules" option should work and respect the "localConvention" option with the "camelCase" value: result 1`] = `
6496+
exports[`"modules" option should work and respect the "localConvention" option with the "camel-case-only" value: result 1`] = `
65036497
[
65046498
[
65056499
"./modules/localsConvention/localsConvention.css",
@@ -6528,11 +6522,11 @@ a {
65286522
]
65296523
`;
65306524

6531-
exports[`"modules" option should work and respect the "localConvention" option with the "camelCase" value: warnings 1`] = `[]`;
6525+
exports[`"modules" option should work and respect the "localConvention" option with the "camel-case-only" value: warnings 1`] = `[]`;
65326526

6533-
exports[`"modules" option should work and respect the "localConvention" option with the "camelCaseOnly" value: errors 1`] = `[]`;
6527+
exports[`"modules" option should work and respect the "localConvention" option with the "camelCase" value: errors 1`] = `[]`;
65346528

6535-
exports[`"modules" option should work and respect the "localConvention" option with the "camelCaseOnly" value: module 1`] = `
6529+
exports[`"modules" option should work and respect the "localConvention" option with the "camelCase" value: module 1`] = `
65366530
"// Imports
65376531
import ___CSS_LOADER_API_NO_SOURCEMAP_IMPORT___ from "../../../../src/runtime/noSourceMaps.js";
65386532
import ___CSS_LOADER_API_IMPORT___ from "../../../../src/runtime/api.js";
@@ -6561,17 +6555,21 @@ a {
65616555
// Exports
65626556
___CSS_LOADER_EXPORT___.locals = {
65636557
"foo": \`bar\`,
6558+
"my-btn-info_is-disabled": \`value\`,
65646559
"myBtnInfoIsDisabled": \`value\`,
6560+
"btn-info_is-disabled": \`rmc8ltu8P1VXaeqLNU6N\`,
65656561
"btnInfoIsDisabled": \`rmc8ltu8P1VXaeqLNU6N\`,
6562+
"btn--info_is-disabled_1": \`AooVHuvzAIGXWngdfslc\`,
65666563
"btnInfoIsDisabled1": \`AooVHuvzAIGXWngdfslc\`,
65676564
"simple": \`snmJCrfw3LVnrlx87XVC\`,
6565+
"foo_bar": \`vA4oeh0XymefKJVIJyg1\`,
65686566
"fooBar": \`vA4oeh0XymefKJVIJyg1\`
65696567
};
65706568
export default ___CSS_LOADER_EXPORT___;
65716569
"
65726570
`;
65736571

6574-
exports[`"modules" option should work and respect the "localConvention" option with the "camelCaseOnly" value: result 1`] = `
6572+
exports[`"modules" option should work and respect the "localConvention" option with the "camelCase" value: result 1`] = `
65756573
[
65766574
[
65776575
"./modules/localsConvention/localsConvention.css",
@@ -6600,7 +6598,7 @@ a {
66006598
]
66016599
`;
66026600

6603-
exports[`"modules" option should work and respect the "localConvention" option with the "camelCaseOnly" value: warnings 1`] = `[]`;
6601+
exports[`"modules" option should work and respect the "localConvention" option with the "camelCase" value: warnings 1`] = `[]`;
66046602

66056603
exports[`"modules" option should work and respect the "localConvention" option with the "dashes" value: errors 1`] = `[]`;
66066604

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -114,12 +114,12 @@ exports[`validate options should throw an error on the "modules" option with "{"
114114
-> Read more at https://github.com/webpack-contrib/css-loader#modules
115115
Details:
116116
* options.modules.exportLocalsConvention should be one of these:
117-
"asIs" | "camelCase" | "camelCaseOnly" | "dashes" | "dashesOnly" | function
117+
"asIs" | "as-is" | "camelCase" | "camel-case" | "camelCaseOnly" | "camel-case-only" | "dashes" | "dashesOnly" | "dashes-only" | function
118118
-> Style of exported classnames.
119119
-> Read more at https://github.com/webpack-contrib/css-loader#localsconvention
120120
Details:
121121
* options.modules.exportLocalsConvention should be one of these:
122-
"asIs" | "camelCase" | "camelCaseOnly" | "dashes" | "dashesOnly"
122+
"asIs" | "as-is" | "camelCase" | "camel-case" | "camelCaseOnly" | "camel-case-only" | "dashes" | "dashesOnly" | "dashes-only"
123123
* options.modules.exportLocalsConvention should be an instance of function."
124124
`;
125125

‎test/modules-option.test.js

+2-3
Original file line numberDiff line numberDiff line change
@@ -1412,14 +1412,13 @@ describe('"modules" option', () => {
14121412
expect(getErrors(stats)).toMatchSnapshot("errors");
14131413
});
14141414

1415-
it('should work and respect the "localConvention" option with the "camelCaseOnly" value', async () => {
1415+
it('should work and respect the "localConvention" option with the "camel-case-only" value', async () => {
14161416
const compiler = getCompiler(
14171417
"./modules/localsConvention/localsConvention.js",
14181418
{
14191419
modules: {
14201420
mode: "local",
1421-
exportLocalsConvention: "camelCaseOnly",
1422-
namedExport: false,
1421+
exportLocalsConvention: "camel-case-only",
14231422
},
14241423
},
14251424
);

‎test/validate-options.test.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,13 @@ describe("validate options", () => {
4141
{ auto: /custom-regex/ },
4242
{ auto: () => true },
4343
{ exportLocalsConvention: "asIs" },
44+
{ exportLocalsConvention: "as-is" },
4445
{ exportLocalsConvention: "camelCase", namedExport: false },
46+
{ exportLocalsConvention: "camel-case", namedExport: false },
4547
{ exportLocalsConvention: "camelCaseOnly" },
48+
{ exportLocalsConvention: "camel-case-only" },
4649
{ exportLocalsConvention: "dashes", namedExport: false },
47-
{ exportLocalsConvention: "dashesOnly" },
50+
{ exportLocalsConvention: "dashes-only" },
4851
{
4952
exportLocalsConvention: (localName) =>
5053
`${localName.replace(/-/g, "_")}`,

0 commit comments

Comments
 (0)
Please sign in to comment.