close
logologo
指南
配置
插件
API
社区
版本
更新日志
Rsbuild 0.x 文档
English
简体中文
指南
配置
插件
API
社区
更新日志
Rsbuild 0.x 文档
English
简体中文
logologo

开始

介绍
快速上手
功能导航
名词解释

框架

React
Vue
Preact
Svelte
Solid

基础

命令行工具
开发服务器
构建产物
静态资源
HTML
JSON
Wasm
TypeScript
Web Workers
部署静态站点
升级 Rsbuild

配置

配置 Rspack
配置 Rsbuild
配置 SWC

样式

CSS
CSS Modules
CSS-in-JS
Tailwind CSS v4
Tailwind CSS v3
UnoCSS

进阶

路径别名
环境变量
模块热更新
浏览器范围
浏览器兼容性
模块联邦
多环境构建
服务端渲染(SSR)
测试

优化

代码拆分
产物体积优化
提升构建性能
静态资源内联

迁移

从 Rsbuild 0.x 迁移
webpack
Create React App
Vue CLI
Vite
Vite 插件
Modern.js Builder

调试

开启调试模式
构建性能分析
使用 Rsdoctor

常见问题

通用类问题
功能类问题
异常类问题
热更新问题
📝 在 GitHub 上编辑此页
上一页CSS
下一页CSS-in-JS

#CSS Modules

CSS Modules 让我们能以模块化的方式编写 CSS 代码,并且可以在 JavaScript 文件中导入和使用这些样式。使用 CSS Modules 可以自动生成唯一的类名,隔离不同模块之间的样式,避免类名冲突。

Rsbuild 默认支持使用 CSS Modules,无需添加额外的配置。我们约定使用 [name].module.css 文件名来启用 CSS Modules。

以下样式文件会被视为 CSS Modules:

  • *.module.css
  • *.module.less
  • *.module.sass
  • *.module.scss
  • *.module.styl
  • *.module.stylus

#用法示例

在 *.module.css 文件中编写样式:

button.module.css
.red {
  background: red;
}

在 JavaScript 文件中导入样式:

Button.tsx
import styles from './button.module.css';

export default () => {
  return <button className={styles.red}>Button</button>;
};

经过编译后,CSS Modules 中的类名会自动添加一个哈希值,以避免类名冲突:

/* 开发模式下生成的类名 */
.src-App-module__red-hiQIE4 {
  background: red;
}

/* 生产模式下生成的类名 */
.red-hiQIE4 {
  background: red;
}
TIP

参考 自定义类名 来修改生成类名的规则。

#具名导入

如果你倾向于在 CSS Modules 中使用具名导入,可以通过 output.cssModules.namedExport 配置项来开启。

rsbuild.config.ts
export default {
  output: {
    cssModules: {
      namedExport: true,
    },
  },
};

开启后,你可以通过具名导入来引用类名:

Button.tsx
import { red } from './button.module.css';

export default () => {
  return <button className={red}>Button</button>;
};

#CSS Modules 识别规则

在默认情况下,只有 *.module.css 结尾的文件才被视为 CSS Modules 模块。

如果你想将其他 CSS 文件也当做 CSS Modules 模块进行处理,可以通过配置 output.cssModules.auto 来实现。

比如:

export default {
  output: {
    cssModules: {
      auto: (resource) => {
        return resource.includes('.module.') || resource.includes('shared/');
      },
    },
  },
};

设置后,以下两个文件都会被视为 CSS Modules:

import styles1 from './foo.module.css';
import styles2 from './shared/bar.css';

#自定义类名

自定义 CSS Modules 生成的类名也是我们比较常用的功能,你可以使用 output.cssModules.localIdentName 来进行配置。

export default {
  output: {
    cssModules: {
      localIdentName: '[hash:base64:4]',
    },
  },
};

如果你需要自定义 CSS Modules 的其他配置,可以通过 output.cssModules 进行设置。

#全局样式

在某些情况下,你可能需要在 CSS Modules 中使用全局样式,比如覆盖第三方库的样式,或者为特定元素设置全局样式。

CSS Modules 提供了 :global() 伪类选择器来实现这个功能,:global() 内的选择器会保持原始的类名,使它能够正确地匹配全局元素。

styles.module.css
/* 本地选择器,会被哈希化 */
.container {
  padding: 20px;
}

/* 全局选择器,不会被哈希化 */
:global(.foo) {
  color: red;
}

/* 组合使用本地和全局选择器,只有 .wrapper 会被哈希化 */
.wrapper :global(.bar) {
  margin: 10px;
}

你也可以嵌套使用 :global():

card.module.css
.card {
  /* 只影响 .card 内部的 .btn 元素 */
  :global(.btn) {
    background: blue;
  }
}

#类型声明

当你在 TypeScript 代码中引用 CSS Modules 时,TypeScript 可能会提示该模块缺少类型定义:

TS2307: Cannot find module './index.module.css' or its corresponding type declarations.

此时你需要为 CSS Modules 添加类型声明文件,请在项目中创建 src/env.d.ts 文件,并添加相应的类型声明。

  • 方法一:如果项目里安装了 @rsbuild/core 包,你可以直接引用 @rsbuild/core 提供的 预设类型:
/// <reference types="@rsbuild/core/types" />
  • 方法二:手动添加需要的类型声明:
src/env.d.ts
declare module '*.module.css' {
  const classes: { readonly [key: string]: string };
  export default classes;
}
declare module '*.module.scss' {
  const classes: { readonly [key: string]: string };
  export default classes;
}
declare module '*.module.sass' {
  const classes: { readonly [key: string]: string };
  export default classes;
}
declare module '*.module.less' {
  const classes: { readonly [key: string]: string };
  export default classes;
}
declare module '*.module.styl' {
  const classes: { readonly [key: string]: string };
  export default classes;
}
declare module '*.module.stylus' {
  const classes: { readonly [key: string]: string };
  export default classes;
}
  • 方法三:如果你需要使用具名导入来引用类名,可以更松散的类型定义:
src/env.d.ts
declare module '*.module.css';
declare module '*.module.scss';
declare module '*.module.sass';
declare module '*.module.less';
declare module '*.module.styl';
declare module '*.module.stylus';

添加类型声明后,如果依然存在类型错误,请尝试重启当前 IDE,或者调整 env.d.ts 所在的目录,使 TypeScript 能够正确识别类型定义。

#类型生成

上述方法虽然可以解决 CSS Modules 在 TypeScript 中的类型问题,但是无法准确地提示出 CSS Modules 导出了哪些类名。

Rsbuild 支持为 CSS Modules 生成准确的类型声明,你只需要开启 @rsbuild/plugin-typed-css-modules,再执行构建命令,Rsbuild 就会为项目中所有的 CSS Modules 文件生成类型声明文件。

rsbuild.config.ts
import { pluginTypedCSSModules } from '@rsbuild/plugin-typed-css-modules';

export default {
  plugins: [pluginTypedCSSModules()],
};

#示例

例如,创建 src/index.ts 和 src/index.module.css 两个文件:

src/index.ts
import styles from './index.module.css';

console.log(styles.pageHeader);
index.module.css
.page-header {
  color: black;
}

构建后,Rsbuild 会自动生成 src/index.module.css.d.ts 类型声明文件:

src/index.module.css.d.ts
interface CssExports {
  'page-header': string;
  pageHeader: string;
}
declare const cssExports: CssExports;
export default cssExports;

此时再打开 src/index.ts 文件,可以看到 styles 对象已经具备了准确的类型。