bem本身不提升工程化水平,真正起作用的是围绕block__element--modifier建立的约束链——包括目录组织、工具校验、命名审查和团队契约;没有这些,光写card__title和card--featured只是表面功夫。

能直接提升CR效率,但必须靠工具卡死,光靠人眼盯类名结构基本无效。
为什么BEM让Code Review从“猜意图”变成“看名字”
传统写法中看到.title或.btn--large,审查者得切到HTML确认归属、查JS逻辑判断是否影响其他模块。BEM把三层语义硬编码进类名:form-field__label--error明确表示:这是form-field块里的label元素,当前处于error状态。不用点开任何文件,就能判断修改只影响该组件内特定子元素。
常见错误现象:
-
card .title—— 结构选择器,破坏封装,CI阶段应被stylelint-selector-bem-pattern拦截 -
button--blue—— “blue”是视觉值,非业务状态,主题切换时需全局搜索替换 -
user-card__header-inner—— 元素名含位置词inner,暴露DOM路径而非语义,应拆为user-card__header+header__content新block
哪些BEM违规必须在PR阶段拦截
这三类不是风格问题,而是直接影响可维护性的硬伤,人工review极易漏,必须由工具自动阻断:
- 分隔符错误:
user_card(单下划线)、user-card__item(block用短横线,element却用双下划线)——stylelint-selector-bem-pattern无法识别结构,CI校验失效 - 修饰符单独使用:
class="button--loading"没带基础button类——删掉修饰符后样式完全丢失,违反BEM“modifier必须叠加在block或element上”原则 - 嵌套超限:
card__content__title__link——三级element暴露DOM层级,应改为card__title-link或提取link为独立block
如何把BEM审查塞进开发流程里
靠文档和培训没用,开发者手快打错一个字符就绕过规范。真正落地要靠三道机器卡口:
- VS Code 安装
stylelint-config-bem插件,保存即高亮menu__item--active写成menu__item-active(少一个横线)这类错误 - pre-commit hook 中运行
npx stylelint "**/*.scss" --fix,自动修正空格、大小写等低风险问题 - CI 阶段执行
npx stylelint "**/*.{css,scss}" --max-warnings 0,任何BEM违规(如.card h3类型选择器)直接阻断合并
注意:不要在SCSS中用&__item { &__text { } }这种嵌套写法,它生成的CSS仍隐含结构依赖,且IDE无法准确定位类名来源。
React/Vue项目里怎么避免手拼类名
开发者手写className={`card ${isFeatured ? 'card--featured' : ''}`},本质是放弃约束。更稳的做法是提供封装函数:
- React:用
clsx+ 常量对象,例如const cn = (e, m) => `${block}__${e}${m ? '--' + m : ''}`,调用cn('avatar', 'large')生成user-card__avatar--large - Vue 3:在
setup中用computed封装BEM工厂函数,避免每个class都手动拼字符串 - ESLint 规则
no-restricted-imports拦截import styles from './Button.module.scss',强制走工具函数注入
最易被忽略的一点:修饰符值必须原子化。允许button--size-lg,禁止button--width-200px;所有可选modifier应在TS接口里用enum或const约束,否则CR时根本没法判断--mobile-full是不是合法状态。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











