必须安装stylelint-selector-bem-pattern插件并严格配置preset、componentname、ignoreselectors三项参数,否则.btn-primary等非bem写法零报错;selector-class-pattern仅正则匹配字符串,无法校验语义合法性与结构归属关系。

必须装 stylelint-selector-bem-pattern 插件并配齐 preset、componentName、ignoreSelectors 三项参数,否则 .btn-primary、.userList 这类非BEM写法完全不报错。
为什么 selector-class-pattern 规则不能替代 BEM 插件
selector-class-pattern 是纯正则匹配,只看字符串“长得像不像”,不管语义对不对:
-
.card__footer和.card-footer都能被同一正则放过,但后者根本不是 BEM -
.userList也能过,只要正则没禁大写或驼峰 -
.card__image--loading是否真有对应.card块?它不查 -
.card__header__title这种非法三级嵌套?它放行
真正要拦的不是“看起来像”,而是“结构合法 + 语义归属正确”——只有 stylelint-selector-bem-pattern 能识别 block__element--modifier 的三层语法结构。
三项参数缺一不可:preset、componentName、ignoreSelectors
只在 plugins 里声明插件、在 rules 里启用 plugin/selector-bem-pattern 还不够,以下三个字段必须同时存在且配置正确:
-
"preset": "bem":必须是字符串"bem",不是"suit"或"css-modules",否则规则不生效 -
"componentName": "[a-z][a-zA-Z0-9]*":强制块名小写开头、不含_或-,排除.Card、.user-list -
"ignoreSelectors": ["/^\..+:(hover|focus|active|disabled|visited)$/", "/^\.js-.+$/"]:跳过伪类和 JS 控制类,否则.button:hover直接报错
漏掉任一字段,或正则写错(比如把 . 写成 .),规则就形同虚设。
Vue/React 动态类名怎么避免漏检
stylelint-selector-bem-pattern 只检查 CSS 文件里的选择器,对 JS 中拼的字符串完全无感:
-
:class="['card', `card--${status}`]"→card--loading不报错,但缺双下划线 -
className={`btn btn--${theme} ${hasIcon ? 'btn__icon' : ''}`}→ 空格错误、btn__icon脱离上下文都不拦截
解决方案分两层:
- JS 侧封装 BEM 工厂函数,如
const cn = (e, m) => `${BLOCK}${e ? '__' + e : ''}${m ? '--' + m : ''}` - 在 JS 文件里加
eslint-plugin-bem(需额外配置),或用clsx+ TypeScript 类型约束防手拼 - CI 中跑
npx stylelint "**/*.{css,scss,vue}"时,确认 Vue 单文件组件的<style></style>区域被解析为 CSS 内容
VS Code 不标红?先查这三件事
插件装了但编辑器不报错,大概率链路断在中间:
- 确认安装的是官方 Stylelint 扩展(作者 Shinnosuke Watanabe),不是旧版或竞品
-
settings.json里必须有:"stylelint.enable": true和"stylelint.validate": ["css","scss","less"] - 禁用其他 CSS 校验插件(比如 CSS Peek),它们会和 stylelint 抢
control+click跳转逻辑
测试方法:故意写个 .button__icon--large--v2,应立刻标红并提示 “Modifier must not contain double hyphens” —— 如果没反应,说明某处配置没生效。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











