Stylelint 默认不校验 BEM 命名,必须安装 stylelint-selector-bem-pattern 插件并严格配置 preset、componentName 和 ignoreSelectors 三项参数,否则 .btn-primary、.userList 等非BEM写法将全部漏检;selector-class-pattern 仅做字符串正则匹配,无法识别语义合法性与结构归属关系。

stylelint 默认不校验 BEM 命名,装了就报错、配错就放行——关键不在装插件,而在三项参数必须同时生效。
为什么 selector-class-pattern 规则不能替代 BEM 插件?
selector-class-pattern 是正则匹配,它只管字符串长得像不像,不管语义对不对。比如 .card__footer 和 .card-footer 都能被同一正则放过,但后者根本不是 BEM;.userList 也能过,只要正则没禁大写或驼峰。
它无法识别 .card__image--loading 是否真有对应 .card 块,也无法拒绝 .card__header__title 这种非法三级嵌套。
真正需要的不是“看起来像”,而是“结构合法 + 语义归属正确”。
必须配置的三个插件参数:preset、componentName、ignoreSelectors
仅启用 stylelint-selector-bem-pattern 插件还不够,以下三项缺一不可:
• "preset": "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 动态类名怎么避免 lint 漏检?
stylelint-selector-bem-pattern 只检查 CSS 文件里的选择器,对 JS 中拼的字符串完全无感。
常见漏检场景:
• :class="['card', `card--${status}`]" → card--loading 不报错,但缺双下划线
• className={`btn btn--${theme} ${hasIcon ? 'btn__icon' : ''}`} → 空格错误、btn__icon 脱离上下文都不拦截
解决方案:
• 封装 BEM 工厂函数,如 const cn = (e, m) => `${BLOCK}${e ? '__' + e : ''}${m ? '--' + m : ''}`
• 在 JS 文件里也加 eslint-plugin-bem(需额外配置),或用 clsx + 类型约束防止手拼
• CI 中跑 npx stylelint "**/*.{css,scss,vue}" 时,务必确认 Vue 单文件组件的 <style> 区域被解析为 CSS 内容
VS Code 里没报错?先查这三件事
插件装了但编辑器不标红,大概率是链路断在中间:
• 确认 VS Code 安装的是官方 Stylelint 扩展(作者 Shinnosuke Watanabe),不是旧版或竞品
• settings.json 中必须有:
"stylelint.enable": true
"stylelint.validate": ["css", "scss", "less", "vue"]
• 禁用其他 CSS 校验插件(如 CSS Peek、Auto Rename Tag),它们会劫持 Ctrl+Click 并干扰 lint 通道
测试方法:在 .css 文件里写 .button__icon--large--v2,应立刻提示 Modifier must not contain double hyphens
BEM 工具链最脆弱的地方不是配置难,而是规则一旦漏掉 ignoreSelectors 或写错 componentName 正则,就会让所有非 BEM 类名静默通过——等上线才发现 .modal-close-btn 满屏飞,再补已经晚了。
stylelint-selector-bem-pattern 插件还不够,以下三项缺一不可:•
"preset": "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 动态类名怎么避免 lint 漏检?
stylelint-selector-bem-pattern 只检查 CSS 文件里的选择器,对 JS 中拼的字符串完全无感。
常见漏检场景:
• :class="['card', `card--${status}`]" → card--loading 不报错,但缺双下划线
• className={`btn btn--${theme} ${hasIcon ? 'btn__icon' : ''}`} → 空格错误、btn__icon 脱离上下文都不拦截
解决方案:
• 封装 BEM 工厂函数,如 const cn = (e, m) => `${BLOCK}${e ? '__' + e : ''}${m ? '--' + m : ''}`
• 在 JS 文件里也加 eslint-plugin-bem(需额外配置),或用 clsx + 类型约束防止手拼
• CI 中跑 npx stylelint "**/*.{css,scss,vue}" 时,务必确认 Vue 单文件组件的 <style> 区域被解析为 CSS 内容
VS Code 里没报错?先查这三件事
插件装了但编辑器不标红,大概率是链路断在中间:
• 确认 VS Code 安装的是官方 Stylelint 扩展(作者 Shinnosuke Watanabe),不是旧版或竞品
• settings.json 中必须有:
"stylelint.enable": true
"stylelint.validate": ["css", "scss", "less", "vue"]
• 禁用其他 CSS 校验插件(如 CSS Peek、Auto Rename Tag),它们会劫持 Ctrl+Click 并干扰 lint 通道
测试方法:在 .css 文件里写 .button__icon--large--v2,应立刻提示 Modifier must not contain double hyphens
BEM 工具链最脆弱的地方不是配置难,而是规则一旦漏掉 ignoreSelectors 或写错 componentName 正则,就会让所有非 BEM 类名静默通过——等上线才发现 .modal-close-btn 满屏飞,再补已经晚了。
• 确认 VS Code 安装的是官方
Stylelint 扩展(作者 Shinnosuke Watanabe),不是旧版或竞品•
settings.json 中必须有:"stylelint.enable": true"stylelint.validate": ["css", "scss", "less", "vue"]• 禁用其他 CSS 校验插件(如 CSS Peek、Auto Rename Tag),它们会劫持
Ctrl+Click 并干扰 lint 通道测试方法:在
.css 文件里写 .button__icon--large--v2,应立刻提示 Modifier must not contain double hyphens
BEM 工具链最脆弱的地方不是配置难,而是规则一旦漏掉 ignoreSelectors 或写错 componentName 正则,就会让所有非 BEM 类名静默通过——等上线才发现 .modal-close-btn 满屏飞,再补已经晚了。


















