必须显式锁定componentname正则以 enforce bem约束,禁用大驼峰、下划线开头等非法命名;pre-commit需精准过滤变更scss文件并避免自动fix;html class属性、js拼接、第三方代码均需配套校验与封装方案。

stylelint-selector-bem-pattern 配置必须锁定 componentName 正则
不锁死 componentName,就等于放行所有类名拼写——比如允许 .Btn、.card-2、_header,这些都会绕过 BEM 约束。官方默认值过于宽松,实际项目必须显式限定。
-
componentName: '[a-z][a-zA-Z0-9]+':强制小写字母开头,禁用大驼峰(CardTitle)、下划线开头(_input)、数字开头(1col-layout) - 若团队用中划线分隔(如
search-form),正则要改为'[a-z][a-z0-9]+(-[a-z0-9]+)*',否则search-form__input会被判错 - 禁止使用泛义块名?靠文档没用,得让 rule 直接报错:
main、content、box不在白名单里,就得靠postcss-bem-linter的components配置拦截
pre-commit 钩子只校验暂存区文件,且不能自动 --fix
很多人把 stylelint "**/*.scss" 塞进 husky,结果每次提交都扫全量文件,CI 超时、本地卡顿、误报 legacy 代码——根本原因是没过滤真实变更。
- 必须用
git diff --cached --name-only --diff-filter=ACM | grep '\.scss$'提取本次提交的样式文件 - 脚本开头加
cd $(git rev-parse --show-toplevel),否则.stylelintrc.js找不到,规则失效 -
stylelint --fix绝对不能出现在 pre-commit:它改文件但不重新git add,导致违规代码照常提交;修复必须由开发者手动触发
HTML 层也要校验 class 属性值
CSS 文件合规,不代表 HTML 里写的类名就对——JS 拼字符串、复制粘贴、手写漏双下划线,这些都在 HTML 中暴露。光查 CSS 是盲区。
- 用
html-validate配合自定义 rule,正则匹配class属性值:^[a-z][a-z0-9-]*(__[a-z][a-z0-9-]*)?(--[a-z][a-z0-9-]*)?$ - 重点拦截两类错误:
card__title--large--dark(嵌套 modifier)、card__title-large(单短横,应为双短横) - 第三方库或 legacy 片段里的
class="btn btn-primary"不要硬改,而是加白名单例外配置,避免阻塞提交
React/Vue 中禁止手拼 className 字符串
再熟的开发者,也会在 className={`card${props.isHovered ? ' card--hovered' : ''}`} 里漏空格、错大小写、混用单双引号——这不是粗心,是手动拼接本身不可靠。
- 统一封装 BEM 工厂函数:
const cn = (e, m) => `${BLOCK}__${e}${m ? '--' + m : ''}`,调用cn('header', 'sticky')→card__header--sticky - ESLint 规则
no-restricted-syntax拦截 JSX 中出现className={.*\+\+.*}或模板字符串含__/--的硬编码 - TS 接口约束 modifier 可选值:
type ButtonVariant = 'primary' | 'outline';,杜绝button--red这类语义断裂写法
class 前,有没有人真问一句:“这个样式属于谁?它会不会在别的上下文里意外生效?”——工具能拦住 90% 的错,剩下那 10%,得靠这句提问守住。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











