react中bem静默失效的根源是文件名、css类名、jsx访问三者未对齐:button.tsx必须配button.module.css,类名须为.button__icon,jsx中须用styles['button__icon']访问。

styles.button__icon 返回 undefined,不是 CSS 写错了,而是文件名、类名、JSX 访问三者没对齐——这是 React 中 BEM 静默失效最常见也最隐蔽的根源。
文件名必须和组件名完全一致(PascalCase)
CSS Modules 的哈希前缀直接取自文件名:Button.module.css → 编译后类名前缀是 Button_button__xxx;如果文件叫 button.module.css 或 MyButton.module.css,styles.button__icon 就永远查不到。
-
Button.tsx必须配Button.module.css,不能是小写或带前缀/后缀 - 文件名大小写敏感:Windows 下可能不报错,但 Linux 构建会失败
- 验证方式:编译后打开 dist 中的 CSS 文件,确认类名是否以
Button_开头
类名必须以 .block 开头,Element 用双下划线
BEM 的语义依赖 Block 名作为命名空间,CSS Modules 只认以文件名小写形式开头的类。比如 Button.module.css 里只允许 .button、.button__icon、.button--primary —— 其他如 .btn__icon、.ui-button、.button-icon 都不会被映射进 styles 对象。
-
.button__icon✅ 参与映射;.button-icon❌ 是普通类,styles['button-icon']为undefined - 禁止混写多个 Block:
Button.module.css里不能出现.modal__close - Element 不可脱离 Block 独立存在:
card__title合法,title或__title都非法
JSX 中必须用字符串键访问 styles
styles.button__icon 是语法错误:点号访问会触发 TS/JS 报错(因为 __ 不是合法标识符),且绕过所有校验。正确路径是先生成原始类名,再通过 styles['...'] 查真实哈希值。
- ❌
className={styles.button__icon}→ 报错或undefined - ✅
className={styles['button__icon']}→ 安全访问 - 动态拼接必须走
bem()工厂 +classnames:例如cn(styles['button'], styles[buttonBem.m('disabled')])
别手写字符串,用 bem() 工厂固化 Block 名
写 {`button ${isDisabled ? 'button--disabled' : ''}`} 表面快,实则埋雷:空格漏写、连字符错位(button-disabled)、isDisabled === null 导致多余空白,且 TypeScript 完全无法约束。
- 封装一次:
const buttonBem = bem('button'),之后所有类名都派生自它 -
buttonBem()→'button',buttonBem.e('icon')→'button__icon',buttonBem.m('primary')→'button--primary' - 传给
classnames的每个值,都必须是buttonBem.xxx()的返回结果,禁用字面量字符串
styles 对象稳定产出可预测的键”。一旦文件名或类名偏离约定,styles['button__icon'] 就是 undefined,DOM 上只剩空 class="",控制台还不报错——这种静默失效,比报错更难定位。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











