CSS Modules 在 React 中默认可用,但需严格遵循文件命名(如 Button.module.css)和导入规则,否则样式仍为全局;仅匹配 /.module.(css|scss|sass|less|styl)$/ 的文件启用模块化,className={styles.xxx} 是唯一合法用法,不支持字符串拼接或动态键访问。

CSS Modules 在 React 中默认可用,但必须严格遵循文件命名和导入规则,否则仍是全局样式。
文件名必须带 .module.css(或对应预处理器后缀)
CRA、Vite 等现代脚手架只对匹配 /\.module\.(css|scss|sass|less|styl)$/ 的文件启用模块化逻辑。写成 Button.css 或 Button.scss,哪怕内容完全一样,构建时也不会哈希类名,import styles from 得到的是空对象或原始类名,最终样式仍全局生效。
- ✅ 正确命名:
Button.module.css、Header.module.scss、Dialog.module.less - ❌ 错误命名:
Button.css、button.Module.CSS(大小写不敏感但推荐全小写)、Button.modules.css(拼写错误) - 路径引用错误也会导致
styles为空——检查是否漏掉./,或大小写与实际文件不符(尤其在 macOS/Linux)
className={styles.xxx} 是唯一合法用法
CSS Modules 导出的是一个 plain object,键为原始类名,值为编译后的哈希字符串(如 Button_button__axY7)。它不支持字符串拼接、动态键访问或非模块化写法。
- ✅ 正确:
className={styles.button}、className={clsx(styles.button, props.primary && styles.primary)} - ❌ 错误:
className="button"(退化为全局)、className={styles['btn-' + type]}(TS 报错,运行时可能undefined) - ❌ 错误:
styleName="button"(这是已废弃的react-css-modules语法,与 CRA 不兼容) - 若需条件组合多个类,必须用
clsx或classnames,不能靠模板字符串拼接
嵌套、伪类和全局穿透的写法限制
CSS Modules 不支持传统后代选择器(如 .container .item),因为两个类会被分别哈希,选择器无法匹配。所有样式必须绑定到同一个哈希类上,或显式退出模块作用域。
立即学习“前端免费学习笔记(深入)”;
- ✅ 推荐伪类写法:
.button { color: blue; } .button:hover { color: red; }(自动作用于同一哈希类) - ✅ 复用其他模块:
.primary { composes: button from './Base.module.css'; } - ✅ 全局穿透:
:global(.third-party-modal) { z-index: 9999; }(必须包在:global()内,否则无效) - ❌ 禁止写法:
.container .item { ... }、:local(.title) { ... }(:local是默认行为,冗余且部分 loader 不识别)
最容易被忽略的是:**CSS Modules 是构建时能力,不是运行时 API**。它不依赖任何 React 特性,也不需要额外安装库——只要文件名对、导入方式对、引用方式对,就自然生效。一旦出问题,90% 是文件后缀或路径写错,而不是配置或语法问题。


















