直接在PR阶段用stylelint拦截BEM违规类名是唯一规模化落地方案;人工CR易漏检分隔符错误、修饰符嵌套、块名非法等问题;需配齐preset、componentName、ignoreSelectors三项参数;仅检查暂存区样式文件;HTML/JSX中类名及第三方组件也需校验。

直接在 PR 阶段用 stylelint 拦截 BEM 违规类名,是目前唯一能规模化落地的方案;靠人工 Code Review 几乎必然漏检,尤其分隔符错误、修饰符嵌套、块名非法等硬伤。
为什么人工 CR 无法可靠识别 BEM 问题
人眼扫 .user-card__title--large--dark 很难立刻判断是否违规——它看起来“像 BEM”,但实际违反了修饰符不可嵌套原则;同理,.card__content__title 的三级嵌套、.Button__header 的大写块名、.menu-item__icon 的单下划线混用,在快速过 PR 时基本不会被注意到。工具能秒级验证结构合法性,人不能。
stylelint-selector-bem-pattern 必须配齐三项参数
只装插件不配置,等于没开检查。以下三项缺一不可:
-
preset: "bem":必须显式指定,填"suit"或留空都不生效 -
componentName: "[a-z][a-z0-9-]*":强制块名小写开头、不含下划线或大写,否则.UserCard、.user_card全部放过 -
ignoreSelectors:至少包含"/^\.js-.+$/"(跳过 JS 控制类)和"/^\..+:(hover|focus|active)$/"(跳过伪类),否则.button:hover直接报错
PR 检查必须只跑暂存区的 CSS/SCSS 文件
CI 中执行 npx stylelint "**/*.{css,scss}" 会扫全量文件,把历史遗留问题全翻出来,掩盖本次提交的真实违规。正确做法是精准过滤:
|Git删除了文件,但还会在Git 仓库历史中遗留。 - 想要从 Git 历史移除敏感信息(密码、密钥、token、私钥) - 想要删除意外提交的大文件 - 想要重写 Git 历史、移除特定文件的所有痕迹 - 提到 "force push"、"重写 commit 历史" - 需要从所有分支、所有 tag 中删除某个文件
立即学习“前端免费学习笔记(深入)”;
- 用
git diff --cached --name-only --diff-filter=ACM | grep '\.scss$'提取本次新增/修改的样式文件 - 脚本开头加
cd $(git rev-parse --show-toplevel),确保stylelint能加载根目录下的配置 - CI 阶段设
--max-warnings 0,任何 BEM 错误直接阻断合并
HTML 和 JSX 中的类名同样需要校验
CSS 文件合规 ≠ 实际渲染合规。常见脱节点:
- JSX 中写
className="card__title--large"却漏了基础类card__title,导致删掉修饰符后样式丢失 - HTML 模板里手写
class="user-card__header",但拼成user-card__header--少一个字母,或user-card_header混用下划线 - 第三方组件如 Ant Design 的
class="ant-btn ant-btn-primary"不符合 BEM,需加白名单忽略,否则阻塞提交
BEM 的约束链必须闭环:CSS 规则 + HTML 使用 + JS 动态拼接,三者任一环节松动,整个规范就失效。最易被忽略的是 componentName 正则没锁死大小写和分隔符——这会让所有表面合规、实则语义错乱的类名畅通无阻。

















