pre-commit 钩子应仅校验暂存区 CSS 文件,需执行三步:cd 到仓库根、git diff 提取变更文件、grep 过滤 CSS;selector-class-pattern 正则须兼容 utility 类与合法 BEM,禁用双连 --,并排除 runtime 状态类;VS Code 需启用 Stylelint 扩展并配置 validate 类型。

pre-commit 钩子里 stylelint 只校验暂存区 CSS 文件
全量扫描 **/*.css 会拖慢提交、误报旧代码,真正该拦的是你刚 git add 进去的那几个文件。
脚本必须包含三步,漏一不可:
- 用
git diff --cached --name-only --diff-filter=ACM提取本次新增/修改/重命名的文件 - 加
| grep '\.css$'过滤出 CSS(单引号防 shell 展开) - 开头必须
cd $(git rev-parse --show-toplevel)切到仓库根,否则stylelint找不到.stylelintrc.cjs
本地开发常在子目录执行 git commit,不加 cd 就直接报路径错误或静默失效。
selector-class-pattern 正则要兼容 utility 类和嵌套 modifier 场景
默认正则只认 block__element--modifier,但实际项目里混着 u-margin-top-16 工具类,或有人手写 card__header--large--dark——后者是非法嵌套,BEM 不允许修饰符连用双 --。
立即学习“前端免费学习笔记(深入)”;
推荐正则(已实测覆盖常见破规):
^(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]+)?))$
注意点:
-
--和__是硬性锚点,写成单-或_,工具链无法识别 - 禁止
card__header--large--dark,应拆成card__header--large card__header--dark - 禁用
selector-max-id等无关规则,它们和 BEM 无关,纯属增加误报
JS 中 className 拼接是最高危破规点
本地看着能跑通,CI 构建时却样式失效,往往因为 button__icon_error 少了个 -,或空格没 trim 干净——这类问题 runtime 不报错,但 class 名无效,样式彻底丢失。
检查重点:
- 所有模板字符串拼接:
className={`card__body ${isExpanded ? 'card__body--expanded' : ''}`,确认每处都严格符合__和-- - 第三方组件 wrapper 类名:如
<el-button class="form-actions__submit-btn">,不能强行把el-button原生类改成 BEM - 避免
is-和--混用:运行时状态(如is-loading)不该进selector-class-pattern校验,它属于 JS 控制层
VS Code 里 stylelint 提示不生效的典型原因
装了插件却没反应?不是配置错,大概率是编辑器没把 CSS 文件交给 stylelint 处理。
必须确认两件事:
- VS Code 安装了官方
Stylelint扩展(作者:Shinnosuke Watanabe) -
settings.json里明确启用并指定校验类型:"stylelint.enable": true"stylelint.validate": ["css","scss","less"] - 禁用其他 CSS 校验插件(比如
CSS Peek),它们会抢control+click跳转逻辑
测试方法:故意写个 .button__icon--large--v2,应立刻标红并提示 “Modifier must not contain double hyphens”——没反应就回头查扩展和配置。
真正的难点不在规则本身,而在于谁来维护这些正则和 ignore 列表。团队引入新组件库或 utility 类体系后,selector-class-pattern 很容易过期,没人更新就等于形同虚设。


















