code review 效率提升的关键在于类名必须明确回答归属模块、角色和状态三问题,严格遵循bem三段式命名(block__element--modifier),杜绝分隔符错误、修饰符嵌套、伪态误用、空格选择器、跨块组合及元素嵌套,并通过stylelint和规范化工厂函数保障一致性。

Code Review 效率提升的关键,不是让 reviewer 多看几眼类名,而是让类名本身就能回答三个问题:它属于哪个业务模块?它在模块里扮演什么角色?当前处于什么状态?BEM 的 block__element--modifier 结构就是为这个目的设计的——不用切 HTML、不查组件目录、不翻文档,一眼可判。
看到类名就该立刻判断合规性
人工扫 CSS 或 HTML 时,类名是否合规应是条件反射。不是“好像对”,而是“必须满足三段式且无歧义”。
-
.title、.btn、.header:缺块名,无法定位归属,直接打回 -
card-title、user_avatar:分隔符错误(单连字符/单下划线),工具链无法识别为 BEM,stylelint-selector-bem-pattern默认不校验 -
button--primary--loading:修饰符嵌套,违反 BEM 原则,也触发allowMultipleDashes: false报错 -
modal__close--hover:伪态不应进修饰符,应写成modal__close:hover,否则 JS 控制状态时逻辑错位
审查选择器时重点盯结构破坏点
BEM 的隔离能力全靠命名空间,一旦选择器用空格或类型标签“破壁”,整个模块就失去可维护性。这类错误在 PR 里极隐蔽,但影响巨大。
-
.card .card__title:带空格即失效,BEM 要求所有类必须直出在元素上,不能靠父级推导 -
form-field p:类型选择器完全丢失上下文,无法追溯样式归属,且易被全局p规则污染 -
header__button--submit:按钮不属于header块,应独立为button块,跨块组合破坏职责边界 -
card__header__title:元素不可嵌套元素,必须拆成card__header+card__title
必须用 stylelint 拦截三类人眼盲区问题
靠人盯类名,漏检率极高。以下三类问题几乎不可能靠肉眼发现,但会直接导致重构断裂、样式错位、响应式失效:
-
card card--featured出现在 HTML,但 CSS 只定义了.card--featured:删掉基础类,样式全崩,且无任何 warning -
card__title被误用在非card容器中(如<div class="user-card"><span class="card__title">):语义错配,但浏览器照常渲染 <li> <code>input--width-200px:把具体值塞进修饰符,换 rem 或加媒体查询就得全局搜改,且语义丢失(到底是“宽”还是“紧凑态”?) - Vue 3 推荐用
computed封装 BEM 工厂:bem('card').el('body'),确保 block 名统一来源 - React 必须用
clsx,且所有参数基于常量:clsx(CARD_BLOCK, isDisabled && `${CARD_BLOCK}--disabled`) - 禁止在模板里硬编码
card__title;禁止在 JS 里写el.classList.add('card__title')—— 这类写法等于放弃 BEM 的可追溯性
配置关键项:componentName: "[a-z][a-zA-Z0-9]*"(禁用大驼峰/数字开头/下划线开头),styleType: "bem"(别填 suit),ignoreSelectors: ["/^\.js-/"](放过 JS 控制类)。
审查 Vue/React 组件时重点看 class 拼接方式
动态 class 是 BEM 最大破口。手拼字符串 class="card__body" 或 className={`${base}--${mod}`} 看似简单,实则让 IDE 跳转失效、搜索失准、重构漏改一处就静默断链。
真正卡住效率的,从来不是“要不要用 BEM”,而是“有没有守住 __ 和 -- 这两个字符的绝对正确性”。少一个下划线,工具链就跳过校验;多一个连字符,VS Code 就不会同步重命名;修饰符写错位置,JS 状态控制和 CSS 样式就永远对不上号。











