Skip to content

Commit

Permalink
feat: exportLocalsConvention option could be a function
Browse files Browse the repository at this point in the history
  • Loading branch information
cap-Bernardito committed Jul 19, 2021
1 parent cc0c1b4 commit ae7850e
Show file tree
Hide file tree
Showing 11 changed files with 443 additions and 12 deletions.
56 changes: 55 additions & 1 deletion README.md
Expand Up @@ -1031,6 +1031,9 @@ module.exports = {
};
```

To set a custom name for namedExport, can use [`exportLocalsConvention`](#exportLocalsConvention) option as a function.
Example below in the [`examples`](#examples) section.

##### `exportGlobals`

Type: `Boolean`
Expand Down Expand Up @@ -1060,11 +1063,13 @@ module.exports = {

##### `exportLocalsConvention`

Type: `String`
Type: `String|Function`
Default: based on the `modules.namedExport` option value, if `true` - `camelCaseOnly`, otherwise `asIs`

Style of exported class names.

###### `String`

By default, the exported JSON keys mirror the class names (i.e `asIs` value).

> ⚠ Only `camelCaseOnly` value allowed if you set the `namedExport` value to `true`.
Expand Down Expand Up @@ -1110,6 +1115,30 @@ module.exports = {
};
```

###### `Function`

**webpack.config.js**

```js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
modules: {
exportLocalsConvention: function (name) {
return name.replace(/-/g, "_");
},
},
},
},
],
},
};
```

##### `exportOnlyLocals`

Type: `Boolean`
Expand Down Expand Up @@ -1434,6 +1463,31 @@ module.exports = {
};
```

### Named export with custom export names

**webpack.config.js**

```js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "css-loader",
options: {
modules: {
namedExport: true,
exportLocalsConvention: function (name) {
return name.replace(/-/g, "_");
},
},
},
},
],
},
};
```

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

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 `mode` 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.
Expand Down
12 changes: 11 additions & 1 deletion src/index.js
Expand Up @@ -216,7 +216,17 @@ export default async function loader(content, map, meta) {
}

const importCode = getImportCode(imports, options);
const moduleCode = getModuleCode(result, api, replacements, options, this);

let moduleCode;

try {
moduleCode = getModuleCode(result, api, replacements, options, this);
} catch (error) {
callback(error);

return;
}

const exportCode = getExportCode(
exports,
replacements,
Expand Down
19 changes: 13 additions & 6 deletions src/options.json
Expand Up @@ -145,12 +145,19 @@
"exportLocalsConvention": {
"description": "Style of exported classnames.",
"link": "https://github.com/webpack-contrib/css-loader#localsconvention",
"enum": [
"asIs",
"camelCase",
"camelCaseOnly",
"dashes",
"dashesOnly"
"anyOf": [
{
"enum": [
"asIs",
"camelCase",
"camelCaseOnly",
"dashes",
"dashesOnly"
]
},
{
"instanceof": "Function"
}
]
},
"exportOnlyLocals": {
Expand Down
15 changes: 15 additions & 0 deletions src/utils.js
Expand Up @@ -485,6 +485,10 @@ function getFilter(filter, resourcePath) {
}

function getValidLocalName(localName, exportLocalsConvention) {
if (typeof exportLocalsConvention === "function") {
return exportLocalsConvention(localName);
}

if (exportLocalsConvention === "dashesOnly") {
return dashesCamelCase(localName);
}
Expand Down Expand Up @@ -588,6 +592,7 @@ function getModulesOptions(rawOptions, loaderContext) {
}

if (
typeof modulesOptions.exportLocalsConvention === "string" &&
modulesOptions.exportLocalsConvention !== "camelCaseOnly" &&
modulesOptions.exportLocalsConvention !== "dashesOnly"
) {
Expand Down Expand Up @@ -970,6 +975,16 @@ function getExportCode(exports, replacements, needToUseIcssPlugin, options) {
};

for (const { name, value } of exports) {
if (typeof options.modules.exportLocalsConvention === "function") {
addExportToLocalsCode(
options.modules.exportLocalsConvention(name),
value
);

// eslint-disable-next-line no-continue
continue;
}

switch (options.modules.exportLocalsConvention) {
case "camelCase": {
addExportToLocalsCode(name, value);
Expand Down

0 comments on commit ae7850e

Please sign in to comment.