编写规则
请帮助我们创建、增强和调试我们的规则!
添加规则
您应该准备好贡献代码。
定义规则
规则必须是
- 仅适用于标准 CSS 语法
- 通常有用;不与特殊模式绑定
并且具有
- 明确的完成状态
- 单一目的,不与其他规则重叠
它的名称分为两部分
- 规则应用于的事物,例如
at-rule
- 规则检查的内容,例如
disallowed-list
除非它适用于整个源代码,否则没有第一部分。
编写测试
您应该为所有被认为是
- 问题的模式
- 不被认为是问题的模式
您应该使用
- 真实的 CSS,避免使用省略号
- 尽可能少的代码,例如,如果针对选择器,则使用空规则
{}
用于空规则,而不是{ }
- 默认情况下使用
a
类型选择器 - 默认情况下使用
@media
at-rules - 默认情况下使用
color
属性 - 默认情况下使用
red
值 - 默认情况下使用
(min-)width
媒体特征 - foo、bar 和 baz 用于名称,例如
.foo
、#bar
、--baz
您应该
- 在测试中改变列和行位置
- 至少包含一个具有 2 个警告的测试
- 在
isStandardSyntax*
实用程序中测试非标准语法,而不是在规则本身中测试
常见的被忽略的边缘情况
您应该问问自己,您的规则如何处理
- 变量(例如
var(--custom-property)
)? - CSS 字符串(例如
content: "anything goes";
)? - CSS 注释(例如
/* anything goes */
)? - 空函数(例如
var()
)? url()
函数,包括数据 URI(例如url(anything/goes.jpg)
)?- 供应商前缀(例如
@-webkit-keyframes name {}
)? - 大小写敏感(例如
@KEYFRAMES name {}
)? - 伪类组合与伪元素(例如
a:hover::before
)? - 嵌套(例如,您是否解析
& a {}
,或者按原样检查它?)? - 空格和标点符号(例如,比较
rgb(0,0,0)
与rgb(0, 0, 0)
)?
编写规则
编写规则时,您应该
- 默认情况下使规则严格
- 添加辅助
ignore
选项以使规则更宽松 - 不包含特定于 SCSS 等语言扩展的代码
您应该使用
- PostCSS API
- 特定于构造的解析器
- 实用程序函数
PostCSS API
使用PostCSS API 导航和分析 CSS 语法树。我们建议使用 walk
迭代器(例如 walkDecls
),而不是使用 forEach
循环遍历节点。
在节点上使用数组方法时,例如 find
、some
、filter
等,您应该在尝试访问其他属性之前显式检查节点的 type
属性。例如
const hasProperty = nodes.find(
({ type, prop }) => type === "decl" && prop === propertyName
);
从PostCSS AST 访问原始字符串时,使用 node.raws
而不是 node.raw()
。
特定于构造的解析器
根据规则,我们还建议使用
与正则表达式或 indexOf
搜索相比,使用这些解析器有很大的好处(即使它们并不总是性能最好的方法)。
实用程序函数
Stylelint 有实用程序函数,这些函数在现有规则中使用,也可能对您有用。请查看这些函数,以便您知道有哪些可用函数。(如果您有新的函数,您认为可能普遍有用,请将其添加到列表中!)。
使用
validateOptions()
实用程序来警告用户有关无效选项isStandardSyntax*
实用程序来忽略非标准语法
添加选项
每个规则都可以接受一个主选项和一个可选的辅助选项。
仅当选项解决请求的用例时才将其添加到规则中,以避免使用未使用的功能污染工具。
主选项
每个规则必须有一个主选项。例如,在
"font-weight-notation": "numeric"
中,主选项是"numeric"
"selector-max-type": [2, { "ignoreTypes": ["custom"] }]
中,主选项是2
规则的命名是为了鼓励使用显式的主选项。例如,font-weight-notation: "numeric"|"named-where-possible"
而不是 font-weight-numeric: "always"|"never"
。因为 font-weight-named: "never"
暗示总是使用数字,而 font-weight-notation: "numeric"
使其明确。
辅助选项
某些规则需要额外的灵活性来解决边缘情况。这些规则可以使用可选的辅助选项对象。例如,在
"font-weight-notation": "numeric"
中没有辅助选项对象"selector-max-type": [2, { "ignore": ["descendant] }]
中,辅助选项对象是{ "ignore": ["descendant] }
最典型的辅助选项是 "ignore": []
和 "except": []
。
关键字 "ignore"
和 "except"
"ignore"
和 "except"
选项接受一个预定义关键字选项数组,例如 ["relative", "first-nested", "descendant"]
"ignore"
跳过特定模式"except"
反转特定模式的主选项
用户定义的 "ignore*"
某些规则接受一个用户定义的忽略项列表。这采用 "ignore<Things>": []
的形式,例如 "ignoreAtRules": []
。
ignore*
选项允许用户在配置级别忽略非标准语法。例如,
- CSS 模块中引入的
:global
和:local
伪类 - SCSS 中引入的
@debug
和@extend
at-rules
方法和语言扩展的出现和消失很快,这种方法确保我们的代码库不会因过时事物的代码而变得杂乱无章。
如果您的规则可以接受数组作为其主选项,则必须通过在规则函数上设置属性 primaryOptionArray = true
来指定这一点。例如
function rule(primary, secondary) {
return (root, result) => {
/* .. */
};
}
rule.primaryOptionArray = true;
module.exports = rule;
这里有一个注意事项:如果您的规则接受一个主选项数组,它也不能接受一个主选项对象。只要有可能,如果您希望您的规则接受一个主选项数组,您应该使数组成为唯一可能性,而不是允许使用各种数据结构。
添加问题消息
以以下形式添加问题消息
- "预期 [某些内容] [在某些上下文中]"
- "意外 [某些内容] [在某些上下文中]"
如果规则具有自动修复功能,请使用
- '预期 "[未修复]" 为 "[已修复]"' 用于短字符串
- '预期 "[主选项]" ... 表示法' 用于长字符串
添加自动修复
根据规则,可以使用PostCSS API 通过修改 PostCSS AST(抽象语法树)来自动修复规则的问题。
将 meta.fixable = true
设置为规则
const meta = {
url: /* .. */,
+ fixable: true,
};
将 context
变量添加到规则参数中
-function rule(primary, secondary) {
+function rule(primary, secondary, context) {
return (root, result) => {
/* .. */
};
}
context
是一个对象,它可能具有三个属性
configurationComment
(字符串):字符串,用于前缀配置注释,例如/* stylelint-disable */
。fix
(布尔值):如果为true
,则您的规则可以应用自动修复。newline
(字符串):当前 lint 文件中使用的换行符。
如果 context.fix
为 true
,则使用 PostCSS API 更改 root
,并在调用 report()
之前提前返回。
if (context.fix) {
// Apply fixes using PostCSS API
return; // Return and don't report a problem
}
report(/* .. */);
编写 README
每个规则都附带一个以下格式的 README
- 规则名称。
- 单行描述。
- 原型代码示例。
- 扩展描述(如有必要)。
- 选项。
- 被认为是问题的示例模式(对于每个选项值)。
- 不被认为是问题的示例模式(对于每个选项值)。
- 可选选项(如果适用)。
单行描述采用以下形式
- "禁止 ..." 用于
no
规则 - "限制 ..." 用于
max
规则 - "要求 ..." 用于接受
"always"
和"never"
选项的规则 - "指定 ..." 用于其他所有内容
您应该
- 从测试中选择示例
- 仅在示例和选项中使用标准 CSS 语法
- 添加尽可能少的示例来传达规则的意图,而不是显示边缘情况
- 在
css
代码围栏之前使用<!-- prettier-ignore -->
- 使用“此规则”来指代规则,例如“此规则忽略 ...”
- 将原型代码示例中的箭头与突出显示的构造的开头对齐
- 将原型代码示例中的文本尽可能地向左对齐
例如
@media screen and (min-width: 768px) {}
/** ↑ ↑
* These names and values */
查看其他规则的 README 文件,以了解更常见的模式。
连接规则
最后一步是在以下位置添加对新规则的引用
向规则添加选项
您应该
- 准备好贡献代码。
- 添加新的单元测试来测试该选项。
- 更改规则的验证以允许使用新选项。
- 向规则添加(尽可能少)逻辑以使测试通过。
- 添加有关新选项的文档。
修复规则中的错误
您应该
- 准备好贡献代码。
- 编写失败的单元测试来举例说明错误。
- 调整规则,直到这些新测试通过。
弃用规则
弃用规则并不常见。当你这样做时,你必须
- 将
stylelintReference
链接指向 GitHub 网站上规则 README 的特定版本,以便它始终可访问。 - 添加适当的元数据以将规则标记为已弃用,例如
rule.meta = { deprecated: true }
。
提高规则的性能
你可以使用以下命令对任何给定规则运行基准测试,并使用任何有效的配置
npm run benchmark-rule -- ruleName ruleOptions [ruleContext]
如果 ruleOptions
参数不是字符串或布尔值,则它必须是包含在引号中的有效 JSON。
npm run benchmark-rule -- value-keyword-case lower
npm run benchmark-rule -- value-keyword-case '["lower", {"camelCaseSvgKeywords": true}]'
如果指定了 ruleContext
参数,则将应用相同的过程
npm run benchmark-rule -- value-keyword-case '["lower", {"camelCaseSvgKeywords": true}]' '{"fix": true}'
该脚本加载 Bootstrap 的 CSS(来自其 CDN)并通过配置的规则运行它。
它最终会打印一些简单的统计信息,如下所示
Warnings: 1441
Mean: 74.17598357142856 ms
Deviation: 16.63969674310928 ms
在编写新规则或重构现有规则时,使用这些度量来确定代码的效率。
Stylelint 规则可以多次重复其核心逻辑(例如,检查庞大 CSS 代码库中每个声明的每个值节点)。因此,值得关注性能并尽力改进它!
提高规则的性能是如果你想要一个快速的小项目,这是一个很好的贡献方式。 尝试选择一个规则,看看你是否可以做些什么来加快它的速度。
确保你在你的拉取请求中包含基准测试测量结果!