pre-commit阶段必须用stylelint-selector-bem-pattern卡死bem规范,自动修正低风险问题、强制人工确认高风险错误,并通过函数化类名生成和pr三类硬伤拦截实现零培训落地。

直接上结论:不靠培训、不发文档、不搞投票,只做三件事——用工具卡死新增代码、把类名生成函数化、在 PR 里自动拦截三类硬伤。其他都是干扰项。
pre-commit 阶段必须跑 stylelint 校验
本地提交前就该发现错误,而不是等 CI 报错再返工。很多团队把校验放在 CI,结果开发者反复 push、等构建、改、再 push,节奏全被打断。
- 安装
stylelint-selector-bem-pattern插件,配置componentName: '[a-z][a-zA-Z0-9]+',它会立刻报错:.btn-primary(非 BEM)、.CardTitle(大驼峰)、.header .logo(结构选择器) - 在
package.json的pre-commit脚本中加:npx stylelint "**/*.{css,scss}" --fix,自动修正空格、大小写等低风险问题 - 禁用
--fix对高风险项的处理(如分隔符错误),让它只报错不修——.user_card(单下划线)或.button--primary__text(修饰符挂错位置)必须人工确认
JS 中 class 名必须封装成函数生成
手拼字符串是 BEM 最大破口。本地开发看着正常,CI 构建时因大小写、连字符漏写、空格多一个直接挂掉,且毫无提示。
- 危险写法:
className={`user-card${isFeatured ? ' user-card--featured' : ''}`}——少个空格或漏写user-card基础类,样式就断了 - 推荐封装:
const cn = (e, m) => `user-card${e ? '__' + e : ''}${m ? '--' + m : ''}`,调用cn('avatar', 'compact')得到user-card__avatar--compact - 所有 Block 级组件都导出自己的
cn,禁止跨 Block 复用同一套生成逻辑;icon这种高频复用元素,应独立为 Block,而非拼成button__icon
PR 阶段必须拦截这三类 BEM 硬伤
它们不是“风格建议”,而是会导致工具链失效、重构崩溃、样式污染的结构性问题,人工 Review 几乎 100% 漏检。
-
__或--写错:如.menu_item(单下划线)、.button-disabled(单短横)、.card__title--large--dark(嵌套修饰符)——stylelint-selector-bem-pattern无法识别结构,VS Code 插件补全、PostCSS 提取全部失效 - Modifier 单独使用:
class="button--loading"不带button基础类——删掉修饰符后样式归零,违反 BEM “modifier 必须叠加在 block 或 element 上” 原则 - Element 名含 DOM 路径:
user-card__header-inner、modal__content__title——暴露实现细节,语义断裂,且三级嵌套已超出 BEM 允许层级,应拆为user-card__header+header__content或modal__title
最常被忽略的一点:BEM 的约束力不来自人,而来自工具链对 __ 和 -- 的硬性解析。写错一个字符,VS Code 就不会高亮、stylelint 就不会报错、构建时 CSS Scope 提取就可能漏掉规则——这不是“写得不够好”,是整个语义链断了。落地成败,就卡在这两个符号是否被当成语法边界来对待。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











