Stylelintselector-combinator-allowed-list规则完全指南用白名单约束选择器组合器【免费下载链接】stylelintA mighty CSS linter that helps you avoid errors and enforce conventions.项目地址: https://gitcode.com/gh_mirrors/st/stylelintselector-combinator-allowed-list是 Stylelint 内置的选择器组合器白名单规则用于限定样式表中允许出现的组合器如、、~或后代空格从而从源头约束选择器的书写习惯与可维护性。本文以该规则的官方文档lib/rules/selector-combinator-allowed-list/README.md为主体结合仓库中的规则实现、工具函数与测试用例讲解它的行为特性、配置方法、底层原理以及与selector-combinator-disallowed-list的搭配使用帮助你把它准确落地到实际项目中。规则概述它检查什么selector-combinator-allowed-list的功能一句话概括指定一个允许使用的组合器列表allowed list。凡是出现在选择器中的组合器只要不在该列表中就会被报告为违规。CSS 中的组合器主要包括组合器写法含义后代组合器空格匹配后代元素如a b子组合器匹配直接子元素如a b相邻兄弟组合器匹配紧邻的下一个兄弟如a b通用兄弟组合器~匹配后续所有兄弟如a ~ b列组合器\|\|匹配列Selectors 4 中定义兼容性有限引用组合器reference/for/等用于 ID 引用语法属非标准或特定场景规则文档用如下代码片段直观标注了检查目标a b {} /** ↑ * This combinator */箭头所指的就是本规则检查的对象。例如配置只允许和空格时a b {}与a ~ b {}会被报告而a b {}、a b {}不会。三条关键行为特性除了白名单过滤这一核心逻辑规则文档明确声明了三项行为约定理解它们才能避免配置踩坑。1. 后代组合器的空白会被规范化为单个空格This rule normalizes the whitespace descendant combinator to be a single space.选择器中的后代组合器本质上是空白但书写形式可能是一个空格、多个空格、制表符Tab甚至换行。规则在比较之前会先把任意形式的空白统一规范为单个空格再与配置项比对。这意味着配置 一个空格时a b、a b、a\tb、a\nb都算作使用了后代组合器统一按空格处理反过来如果白名单里不含空格那么任何形式的后代组合器包括换行分隔都会被视为违规。该行为由 normalizeCombinator.mjs 实现实现只有一行正则替换export default function normalizeCombinator(value) { return value.replace(/\s/g, ); }2. 引用组合器reference combinators被忽略This rule ignores reference combinators e.g./for/.形如/for/、/deep/这样被/包裹的引用组合器见 W3C Selectors Level 4 的 idref combinators 规范不会被本规则检查。也就是说即使白名单中没有它们也不会被报告。判定逻辑位于 isStandardSyntaxCombinator.mjs只要组合器节点的value以/开头或以/结尾就直接判定为非标准组合器并跳过// Ignore reference combinators like /deep/ if (node.value.startsWith(/) || node.value.endsWith(/)) { return false; }3. 支持 1 个消息参数被禁止的组合器规则文档注明This rule supports 1 message argument: the disallowed combinator.即使用自定义message时可以通过消息参数把被拒绝的组合器注入到提示文案中。结合 docs/user-guide/configure.md 中关于message次要选项的说明可以这样配置/** type {import(stylelint).Config} */ export default { rules: { selector-combinator-allowed-list: [ [, ], { message: (combinator) 组合器 ${combinator} 不在允许列表中请改用 或后代空格 } ] } };如果配置文件是 JSON不支持函数可以使用printf风格的占位符{ rules: { selector-combinator-allowed-list: [ [, ], { message: Disallowed combinator \%s\ } ] } }消息参数的值来自源码中messages.rejected的定义lib/rules/selector-combinator-allowed-list/index.mjsconst messages ruleMessages(ruleName, { rejected: (combinator) Disallowed combinator ${combinator}, });注意注入的是规范化后的组合器值即空白已被替换为单个空格所以触发a\nb {}时消息中的参数是 而不是原始换行。选项配置Arraystring规则的唯一主要选项primary option是一个字符串数组枚举所有允许出现的组合器[array, of, combinators]例如只允许子组合器和后代组合器{ rules: { selector-combinator-allowed-list: [, ] } }被视为问题的写法Problemsa b {}a ~ b {}因为与~都不在白名单[, ]中。不被视为问题的写法Not considered problemsa b {}a b {}a b {}最后一个例子值得注意a与b分处两行但它是合法的后代组合器写法经空白规范化后等价于单个空格因此在白名单允许范围内不构成问题。该规则还设置了rule.primaryOptionArray trueindex.mjs并从 lib/rules/index.mjs 的规则注册表中可以看到它与selector-combinator-disallowed-list成对存在。源码级原理一条完整的检查链路阅读 index.mjs 的实现可以完整还原规则的执行流程核心链路如下选项校验validateOptions校验主要选项要求数组内每个元素都是字符串possible: [isString]。校验失败则直接返回不产生任何报告。遍历规则节点root.walkRules遍历样式树中的每一条 rule。过滤非标准规则调用 isStandardSyntaxRule.mjs跳过 Less 的:extend规则以及包含插值如 SCSS/Stylus 插值语法等非标准选择器的规则。解析选择器通过 parseSelector.mjs 使用postcss-selector-parser对选择器做 AST 解析解析失败时记录parseError并跳过。获取原始选择器文本的是 getRuleSelector.mjs它会优先使用raws.selector.raw保留源码中的原始空白保证换行、Tab 等信息不丢失。遍历组合器walkCombinators逐个取出选择器中的组合器节点。过滤非标准组合器调用isStandardSyntaxCombinator除忽略引用组合器外还忽略位于容器首部或尾部的组合器节点这些位置不构成真实的关系连接。规范化并比对normalizeCombinator(value)将空白压成单个空格然后判断primary.includes(normalizedValue)——不在白名单中即触发报告。精确定位报告报告位置使用combinatorNode.sourceIndex作为起点终点通过index (raws?.value || value).length计算index.mjs确保编辑器中的高亮范围准确落在组合器字符本身。从代码结构可以推断规则的报告发生在 rule 节点上并携带精确的index/endIndex这与测试断言中的行列号如line: 1, column: 3完全对应。与selector-combinator-disallowed-list的对照使用本规则有一个语义完全相反的孪生规则 selector-combinator-disallowed-list指定禁止的组合器列表。两者的源码结构几乎一致唯一差异在第 47 行附近的判定逻辑allowed-list 在primary.includes(normalizedValue)为true时放行、为false时报告disallowed-list 则恰好相反命中列表即报告。对比项selector-combinator-allowed-listselector-combinator-disallowed-list语义允许列表未列出即违规禁止列表列出即违规示例配置[, ][, ]a b {}不报告报告a b {}不报告报告a b {}报告不报告空白规范化相同相同忽略引用组合器相同相同两条规则的默认消息文案也都是Disallowed combinator …均支持 1 个消息参数。选择哪一条取决于你的风格策略希望只许用某几种就选 allowed-list希望明令禁用某几种例如禁止深嵌套常用的或禁止~依赖就选 disallowed-list。实战配置建议基础接入配置文件Stylelint 从当前目录向上查找stylelint.config.js也支持.mjs、.cjs、.ts详见 docs/user-guide/configure.md。最小可用配置如下/** type {import(stylelint).Config} */ export default { rules: { selector-combinator-allowed-list: [, ] } };常用组合器取值参考后代组合器配置值始终写单个空格 因为任何空白都会被规范化子组合器相邻兄弟通用兄弟~列组合器||如需支持。调整严重级别借助severity次要选项可以把违规从默认的error降级为warning适合渐进式推行阶段{ rules: { selector-combinator-allowed-list: [ [, ], { severity: warning } ] } }局部豁免与其他规则一致该规则也支持stylelint-disable系列注释。测试用例tests/index.mjs验证了stylelint-disable-next-line的豁免能力/* stylelint-disable-next-line selector-combinator-allowed-list */ a b {}测试用例印证仓库为该规则提供了完整的测试覆盖lib/rules/selector-combinator-allowed-list/tests/index.mjs可以用这些用例来验证你对规则行为的理解配置[, ]时接受accept的写法包括a {}无组合器、a, b {}逗号分隔非组合器a /for/ b {}引用组合器被忽略a b {}、a:not(b c) {}组合器出现在:not()内同样会被检查a b {}、a\tb {}、a\nb {}各种空白形式的后代组合器带stylelint-disable-next-line注释的a b {}拒绝reject的写法包括a ~ b {}报错Disallowed combinator ~位置1:3至1:4a:not(b ~ c) {}位置1:9至1:10证明伪类内嵌套选择器也会被递归检查多行a,\nb c {}第二行2:3处报告另一个测试用例使用字符串配置config: ~验证了反向场景a b {}、a\tb {}、a\n\tb {}全部因后代空格不在白名单中而报告Disallowed combinator 。这说明尽管规则文档以数组为示例形式选项校验对单个字符串同样兼容配置时应优先使用数组以保持一致性。小结selector-combinator-allowed-list是 Stylelint 组合器管理家族中的白名单成员与selector-combinator-disallowed-list互补。它通过空白规范化、引用组合器豁免、消息参数支持与精确的源码定位让团队能够以声明式配置统一选择器书写风格。若要深入其实现细节建议从 规则实现、空白规范化工具、标准组合器判定 三个文件入手并结合 测试用例 验证边界行为。【免费下载链接】stylelintA mighty CSS linter that helps you avoid errors and enforce conventions.项目地址: https://gitcode.com/gh_mirrors/st/stylelint创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?