Stylelint 需正确配置插件参数才能校验 BEM:必须同时设置 preset、componentName、ignoreSelectors,且 pre-commit 钩子应仅检查 git add 的 CSS 文件,禁用 --fix,JS 中 className 拼接须封装为类型安全函数。

Stylelint 本身不校验 BEM,装了插件但没配对参数,stylelint 就等于没开——.userList、.card-footer 全部零报错。
pre-commit 钩子里只扫暂存区 CSS 文件
直接跑 stylelint "**/*.css" 会扫全量、超时、误报,真正要卡的是本次 git add 进去的改动文件。
- 用
git diff --cached --name-only --diff-filter=ACM | grep '.css$'提取新增/修改/重命名的 CSS 文件 - 脚本开头必须加
cd $(git rev-parse --show-toplevel),否则stylelint找不到配置文件 - 绝对不要在钩子里加
--fix:它改文件但不git add,提交内容仍是错的,还污染本地工作区
stylelint-selector-bem-pattern 三项参数缺一不可
plugin/selector-bem-pattern 不是开关式规则,preset、componentName、ignoreSelectors 必须同时显式配置,漏一个就形同虚设。
-
"preset": "bem":只能写"bem",写成"suit"或"css-modules"就不解析__和-- -
"componentName": "[a-z][a-zA-Z0-9]*":强制块名小写开头、不含_或-,排除.UserCard、.user-card -
"ignoreSelectors": ["/^\..+:(hover|focus|active|disabled|visited)$/", "/^\.js-.+$/"]:跳过伪类和 JS 控制类,否则.button:hover直接报错
JS 中手拼 className 是最高危破规点
stylelint-selector-bem-pattern 只检查 CSS 文件里的选择器,对 className={`card__header--${size}`} 完全无感——本地能跑通,CI 构建时因空格或大小写敏感直接失效。
立即学习“前端免费学习笔记(深入)”;
- 禁止直接拼字符串:
className="btn btn--lg btn__icon"少个空格或错个-就无效 - 封装 BEM 工厂函数,如
const cn = (e, m) => `${BLOCK}${e ? '__' + e : ''}${m ? '--' + m : ''}`</li> <li>在 JSX/TSX 里用 <code>clsx+ 类型约束(如size: 'sm' | 'md' | 'lg'),而非自由传参
正则 selector-class-pattern 无法替代语义校验
仅靠正则匹配类名格式,拦不住 .card__image--loading 是否真有对应 .card 块,也放行 .card__header__title 这种非法三级嵌套。
- 推荐正则(兼容 utility 类):
^(u-[a-z][a-zA-Z0-9]+|([a-z][a-zA-Z0-9]+(__[a-z][a-zA-Z0-9]+)?(--[a-z][a-zA-Z0-9]+)?))$ - 禁用
selector-max-id等无关规则,它们和 BEM 无关,只增加误报 - 别用
class-name-pattern:这是旧版别名,v14+ 会报Invalid options object
BEM 规范真正的断点不在“怎么写”,而在“谁来维护规则更新”——比如团队引入新组件后,componentName 白名单是否同步,ignoreSelectors 是否覆盖新第三方库类名,这些没人盯,工具链再严也会松动。


















