必须用@projectwallace/postcss-bem-linter,因原版已归档且不支持嵌套解析、SCSS变量内联及修饰符层级识别;它修复三大问题:解析&__title输出、内联$block-name变量、多define注释作用域隔离;校验依赖顶部/ postcss-bem-linter: define .block /注释,缺则所有BEM类报错,且需配置ignore正则跳过js-/is-/has-/u-类。

必须用 @projectwallace/postcss-bem-linter,原版 postcss-bem-linter 已归档,不支持嵌套规则、SCSS 变量内联,也识别不了 .block__elem--mod 中的修饰符层级——装错包,校验就完全静默失效。
为什么 @projectwallace/postcss-bem-linter 是唯一可行选择
它修复了三个关键断点:
- 能正确解析 SCSS 编译后的
&__title输出(如生成.list__title) - 支持
$block-name变量内联(如.#{$prefix}__icon→.card__icon) - 允许多个
/* postcss-bem-linter: define .xxx */共存于同一文件,作用域互不干扰
而原版连 .header__logo 都会报 “element not under block”,不是你写错了,是它根本没能力推断上下文。
/* postcss-bem-linter: define .block */ 必须写在文件顶部
插件不猜、不推、不反查——它只认这一行注释,且必须出现在首个 BEM 类之前。漏掉或位置错,后果直接:
立即学习“前端免费学习笔记(深入)”;
-
.card__footer被判为非法 element -
.card__body--expanded里的--expanded因无归属 block 被标为非法 modifier - 即使 SCSS 里用了
&__content,编译后是.modal__content,插件仍要求顶部写define .modal
不配 ignore 就等于没开校验
默认模式下,.js-toggle、.is-open、.u-hidden 全被当违规类报错。必须在 postcss.config.js 显式跳过:
module.exports = {
plugins: [
require('@projectwallace/postcss-bem-linter')({
preset: 'bem',
ignore: [/^js-/, /^is-/, /^has-/, /^u-/]
})
]
}注意两点:
- 正则必须带
^,否则.button-is-active也会被误放过 - 项目若混用 utility 类(如
.u-text-center)、JS 钩子类(.js-modal-trigger)、状态类(.is-disabled),全得列进ignore
构建链路不通,插件就等于没装
Vite 默认对 .css 文件走 esbuild,绕过 PostCSS;Webpack 若没配 postcss-loader 或顺序错(比如放在 css-loader 后),插件也不会执行。
- Vite:确认
vite.config.ts中css.postcss已启用,且插件在plugins数组里 - Webpack:确保
postcss-loader在css-loader之前,且postcss.config.js路径正确 - 验证是否生效:故意写个错命名,如
.header__logo__icon,看构建是否报错——不报就是链路断了
真正难的不是写对规则,而是让每个 define 注释精准对应真实组件边界,且动态拼接类名(如 class="header__${state}")永远逃逸在校验之外,必须靠 ignore 或提取常量兜底。


















