Stylelint 本身不识别 BEM,需配合 stylelint-selector-bem-pattern 插件校验 __ 和 -- 语法结构,仅检查命名格式合规性(如拒绝 .block_element),不校验语义归属或文件位置,须结合白名单、目录约束与人工共识落地。

Stylelint 能否自动发现 BEM 命名违规
能,但必须配对插件和规则——stylelint 本身不识别 BEM,靠 stylelint-selector-bem-pattern 插件解析 __ 和 -- 的语法结构。它会报错类似:Expected selector ".user_avatar" to match specified BEM pattern,但不会判断 .card__title 是否在 .card 组件文件里被误用。
- 只校验格式:接受
.block__element--modifier,拒绝.block_element或.block--modifier(缺元素层) - 不校验语义:两个不同模块都用
.list__item,只要写法合规,就不会报警 - 需配合
@scope注释或目录约束,否则工具只能管“怎么写”,不管“在哪写”
如何配置 stylelint 让 BEM 规则真正落地
关键不是加插件,而是让规则和团队工作流咬合。以下配置在 VS Code + ESLint + CI 环境中验证有效:
- 安装插件:
npm install --save-dev stylelint stylelint-selector-bem-pattern - 在
.stylelintrc.cjs中启用并限定 block 白名单:plugin:stylelint-selector-bem-pattern/standard,再覆盖componentName为['button', 'card', 'form', 'header'](按你们项目实际模块填) - 禁止全局 CSS 文件出现 BEM 类名:在
rules里加"selector-max-universal": [0, { "ignore: ["css"] }],配合文件路径过滤,比如base.css不走该规则 - VS Code 中启用
stylelint.validate: ["css", "scss"],保存即标红错误,比等 CI 报错快得多
为什么写了 BEM 还被 Stylelint 报错
常见不是插件没装好,而是命名细节踩了语法边界。BEM 对符号、位置、层级有硬性要求,stylelint-selector-bem-pattern 会严格校验:
- 单下划线
.user_profile→ 必须双下划线.user__profile - 修饰符写成
.button-disabled→ 必须双破折号.button--disabled - 元素名含大写字母:
.card__UserAvatar→ 推荐全小写 + 中划线:.card__user-avatar(插件默认启用camelCase检查) - 嵌套过深:
.card__content__title→ BEM 只允许一层__,应改为.card__title或抽新 Block
Stylelint 和 BEM 文件结构怎么联动
纯靠命名规则防不住人绕开约定。真正起效的是把 Stylelint 规则和文件路径、组件目录强绑定:
- 每个组件建独立目录,如
src/components/search-form/,其 CSS 文件开头必须写注释:/* @scope search-form */ - 用
stylelint-selector-bem-pattern的componentName配置,把search-form加入白名单,其他地方写.search-form__input才合法 - CI 中加检查:用
git diff --name-only HEAD~1 | grep '\.scss$' | xargs npx stylelint,只校验本次修改的样式文件,不拖慢全量构建 - 禁用
@extend和@mixin跨 Block 复用:Sass 中若@extend .button出现在modal.scss里,就破坏了作用域,建议改用%button-base占位符
BEM 规范真正卡住人的地方,从来不是“记不住写法”,而是“不知道哪个 block 该叫什么”、以及“老代码里混着一堆 .clearfix .text-center 工具类”。Stylelint 能拦住格式错误,但 block 名是否语义唯一、是否和目录名一致,还得靠代码审查和初期定义共识——工具只是把人定的规则,变成机器可执行的红线。

















