最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
如何配置正则表达式校验CSS BEM类名
时间:2026-09-04 10:56:49 编辑:袖梨 来源:一聚教程网
必须用锚定正则^[a-z][a-zA-Z0-9]+(__[a-z][a-zA-Z0-9]+)?(--[a-z][a-zA-Z0-9]+)?$并白名单扩展u-|is-|js-前缀,否则.btn-primary等违规写法将漏检;但该正则仅校验格式,无法识别语义归属与结构合法性,须配合stylelint-selector-bem-pattern插件及preset、componentName、ignoreSelectors三项完整配置。
selector-class-pattern 正则怎么写才不漏检
直接套最新示例正则会放过 .btn-primary、.userList、.card__header__logo 这类明显违规写法。关键在三点:必须锚定开头结尾、强制小写开头、禁止非法嵌套。
推荐基础 BEM 正则:^[a-z][a-zA-Z0-9]+(__[a-z][a-zA-Z0-9]+)?(--[a-z][a-zA-Z0-9]+)?$
-
^[a-z]:块名必须小写字母开头,拒绝.Card、.1button -
__[a-z]:元素名也必须小写开头,拒绝.block__Header -
(--[a-z])?:修饰符只允许一层,拒绝.block__elem--large--dark - 没加
$就会把.card__title extra-class里的前半段当合法——实际它只是字符串片段
混用 utility 类时正则怎么扩展
项目里不可能只有纯 BEM 类,.u-text-center、.is-open、.js-toggle 必须白名单放行,否则全报错。硬塞进同一正则里会导致规则膨胀、难维护。
正确做法是用逻辑或组合:^(u-[a-z][a-zA-Z0-9]+|is-[a-z][a-zA-Z0-9]+|js-[a-z][a-zA-Z0-9]+|([a-z][a-zA-Z0-9]+(__[a-z][a-zA-Z0-9]+)?(--[a-z][a-zA-Z0-9]+)?)$)
- 每个非 BEM 前缀单独写,如
u-、is-、js-,开头必须带^防止.button-is-active被误放过 - BEM 主体部分仍保留锚点和小写约束,避免
.Block__elem漏检 - 别用
class-name-pattern——这是 v13 旧字段,v14+ 会直接报Invalid options object
为什么正则永远校验不了语义归属
selector-class-pattern 只做字符串匹配,它不管 .card__image 是否真有对应 .card 块,也不拦 .card__header__title 这种非法三级嵌套。
-
.card__image--loading和.card--loading都能过同一正则,但后者才是合法修饰符位置 -
.userList若正则没禁驼峰,就会被当成userList(小写开头+字母数字)放过 -
.btn-primary匹配[a-z]+-[a-z]+?那它就不是 BEM,而是 SUIT 或自定义风格——正则无法判断意图
真正要查“这个 element 是否属于这个 block”,必须用 stylelint-selector-bem-pattern 插件,并配齐 preset、componentName、ignoreSelectors 三项,缺一不可。
Vue/React 动态类名怎么防漏检
selector-class-pattern 只扫 CSS 文件里的静态选择器,对 JS 中 :class="['card', `card--${status}`]" 这类拼接完全无感——card--loading 缺双下划线也不会报。
- JS 侧必须封装生成函数,比如
const bem = (block, elem?, mod?) => `${block}${elem ? '__' + elem : ''}${mod ? '--' + mod : ''}` - 避免手拼字符串:
className={`btn btn--${theme} ${hasIcon ? 'btn__icon' : ''}`}里空格错误、btn__icon脱离上下文,正则都发现不了 - 若要用 ESLint 配合检查,得额外装
eslint-plugin-bem并配置类型约束,否则 TS 也无法拦截运行时字符串
正则校验只是第一道防线,它快、轻量、编辑器友好,但边界清晰:只管“长得像不像”,不管“是不是真的”。想查结构合法性,就得插件上,且得配全参数——少一个,.btn-primary 就安静地躺在代码里。