Skip to content

Commit

Permalink
feat: allow to enable namedExport for CSS Modules (#2475)
Browse files Browse the repository at this point in the history
  • Loading branch information
chenjiahan authored May 30, 2024
1 parent e14d675 commit 742de6c
Show file tree
Hide file tree
Showing 10 changed files with 122 additions and 36 deletions.
15 changes: 6 additions & 9 deletions e2e/cases/css/css-modules-named-export/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,12 @@ rspackOnlyTest(
cwd: __dirname,
runServer: true,
rsbuildConfig: {
tools: {
cssLoader: {
modules: {
// TODO: css-loader need support named export when namedExports: false.
namedExport: true
}
}
}
}
output: {
cssModules: {
namedExport: true,
},
},
},
});
const files = await rsbuild.unwrapOutputJSON();

Expand Down
1 change: 1 addition & 0 deletions packages/core/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ const getDefaultOutputConfig = (): NormalizedOutputConfig => ({
inlineStyles: false,
cssModules: {
auto: true,
namedExport: false,
exportGlobals: false,
exportLocalsConvention: 'camelCase',
},
Expand Down
1 change: 0 additions & 1 deletion packages/core/src/plugins/css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,6 @@ const getCSSLoaderOptions = ({
modules: {
...cssModules,
localIdentName,
namedExport: false,
},
sourceMap: config.output.sourceMap.css,
};
Expand Down
5 changes: 5 additions & 0 deletions packages/shared/src/types/config/output.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,10 @@ export type CSSModules = {
* Controls the level of compilation applied to the input styles.
*/
mode?: CSSLoaderModulesOptions['mode'];
/**
* Whether to enable ES modules named export for locals.
*/
namedExport?: boolean;
};

export type Minify =
Expand Down Expand Up @@ -326,6 +330,7 @@ export interface NormalizedOutputConfig extends OutputConfig {
injectStyles: boolean;
cssModules: {
auto: CSSModules['auto'];
namedExport: boolean;
exportGlobals: boolean;
exportLocalsConvention: CSSModulesLocalsConvention;
localIdentName?: string;
Expand Down
58 changes: 53 additions & 5 deletions website/docs/en/config/output/css-modules.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,11 @@ type CSSModulesLocalsConvention =

Type description:

- `asIs` Class names will be exported as is.
- `camelCase` Class names will be camelized, the original class name will not to be removed from the locals.
- `camelCaseOnly` Class names will be camelized, the original class name will be removed from the locals.
- `dashes` Only dashes in class names will be camelized.
- `dashesOnly` Dashes in class names will be camelized, the original class name will be removed from the locals.
- `asIs`: Class names will be exported as is.
- `camelCase`: Class names will be camelized, the original class name will be exported.
- `camelCaseOnly`: Class names will be camelized, the original class name will not be exported.
- `dashes`: Only dashes in class names will be camelized, the original class name will be exported.
- `dashesOnly`: Dashes in class names will be camelized, the original class name will not be exported.

```ts
export default {
Expand Down Expand Up @@ -232,3 +232,51 @@ modules: {
};
}
```

## cssModules.namedExport

- **Type:** `boolean`
- **Default:** `false`

Whether to enable ES modules named export for class names.

```ts
export default {
output: {
cssModules: {
namedExport: true,
},
},
};
```

### Example

```css title="style.module.css"
.foo {
color: blue;
}
```

- `namedExport: false`:

```js
import styles from './style.module.css';

console.log(styles.foo);
```

- `namedExport: true`:

```js
import { foo } from './style.module.css';
// or
import * as styles from './style.module.css';

console.log(foo);
console.log(styles.foo);
```

```tip
When `namedExport` is set to true, the `default` class exported by CSS Modules will be automatically renamed to `_default` class because `default` is a reserved word in ECMA modules.
```
2 changes: 1 addition & 1 deletion website/docs/en/config/output/externals.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

At build time, prevent some `import` dependencies from being packed into bundles in your code, and instead fetch them externally at runtime.

For more information, please see: [Rspack Externals](https://rspack.dev/config/externals)
> For more information, please see: [Rspack Externals](https://rspack.dev/config/externals).
### Example

Expand Down
8 changes: 1 addition & 7 deletions website/docs/en/config/tools/css-loader.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,7 @@

```js
const defaultOptions = {
modules: {
auto: true,
namedExport: false,
exportLocalsConvention: 'camelCase',
localIdentName: rsbuildConfig.output.cssModules.localIdentName,
exportOnlyLocals: target !== 'web',
},
modules: rsbuildConfig.output.cssModules,
sourceMap: rsbuildConfig.output.sourceMap.css,
// value is `1` when compiling css files, and is `2` when compiling sass/less files
importLoaders: 1 || 2,
Expand Down
58 changes: 53 additions & 5 deletions website/docs/zh/config/output/css-modules.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,11 @@ type CSSModulesLocalsConvention =

类型说明:

- `asIs` 类名将按原样导出。
- `camelCase` 类名将被驼峰化,原始类名仍然可用
- `camelCaseOnly` 类名将被驼峰化,原始类名不可用
- `dashes` 只有类名中的破折号会被驼峰化,原始类名仍然可用
- `dashesOnly` 只有类名中的破折号会被驼峰化,原始类名不可用
- `asIs`类名将按原样导出。
- `camelCase`类名将被驼峰化,然后被导出。原始类名也会被导出
- `camelCaseOnly`类名将被驼峰化,然后被导出。原始类名不会被导出
- `dashes`只有类名中的破折号会被驼峰化,然后被导出。原始类名也会被导出
- `dashesOnly`:类名中的破折号会被驼峰化,然后被导出。原始类名不会被导出

```ts
export default {
Expand Down Expand Up @@ -236,3 +236,51 @@ export default {
},
};
```

## cssModules.namedExport

- **类型:** `boolean`
- **默认值:** `false`

是否具名导出 class names。

```ts
export default {
output: {
cssModules: {
namedExport: true,
},
},
};
```

### 示例

```css title="style.module.css"
.foo {
color: blue;
}
```

- `namedExport: false`:

```js
import styles from './style.module.css';

console.log(styles.foo);
```

- `namedExport: true`:

```js
import { foo } from './style.module.css';
// or
import * as styles from './style.module.css';

console.log(foo);
console.log(styles.foo);
```

```tip
当 namedExport 为 true 时,CSS Modules 导出的 `default` class 会被自动重命名为 `_default` class,因为 default 是 ECMA modules 的保留字。
```
2 changes: 1 addition & 1 deletion website/docs/zh/config/output/externals.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

在构建时,防止将代码中某些 `import` 的依赖包打包到 bundle 中,而是在运行时再去从外部获取这些依赖。

详情请见: [Rspack Externals](https://rspack.dev/zh/config/externals)
> 更多用法供参考:[Rspack Externals](https://rspack.dev/zh/config/externals)
### 示例

Expand Down
8 changes: 1 addition & 7 deletions website/docs/zh/config/tools/css-loader.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,7 @@

```js
const defaultOptions = {
modules: {
auto: true,
namedExport: false,
exportLocalsConvention: 'camelCase',
localIdentName: rsbuildConfig.output.cssModules.localIdentName,
exportOnlyLocals: target !== 'web',
},
modules: rsbuildConfig.output.cssModules,
sourceMap: rsbuildConfig.output.sourceMap.css,
// 在编译 css 文件时为 `1`,在编译 sass/less 文件时为 `2`
importLoaders: 1 || 2,
Expand Down

0 comments on commit 742de6c

Please sign in to comment.