深入解析 ESLint 文档站的 Rule 宏组件:从参数模型到渲染实现
【免费下载链接】eslintFind and fix problems in your JavaScript code.项目地址: https://gitcode.com/GitHub_Trending/es/eslint
本篇文章围绕 ESLint 文档网站中的rule宏组件展开,该组件由 docs/src/_includes/components/rule.macro.html 定义,是 ESLint 规则参考页(Rules Reference)中每条规则卡片的核心渲染单元。读完本文,你将完整掌握该组件的参数模型(名称、描述、废弃/移除状态、替换规则、分类标签)、Nunjucks 宏的导入与调用方式,并结合源码理解其实际渲染逻辑与数据来源,从而能够在 ESLint 仓库的文档体系中自如地新增、维护或复用规则展示组件。
一、组件定位:文档站中的“规则卡片”
ESLint 文档网站(由 docs/src 下的 Eleventy 静态站点构建)使用 docs/src/library/rule.md 记录其组件库(Library)中的rule组件。该组件是一个定义在docs/src/_includes/components/rule.macro.html中的Nunjucks 宏(macro),接受一组参数用于渲染一条规则。
一条规则(rule)在展示层面具有以下核心属性:
- name(名称):规则的标识符,例如
array-bracket-newline; - description(描述):对规则作用的一句话说明;
- deprecated / removed(废弃 / 移除标记):布尔标志,分别表示规则已被废弃或已被移除;
- replacedBy(替换项):可选,指示该规则被哪条(哪些)规则替代;
- categories(分类对象):描述规则的分类属性,例如是否属于
recommended、是否可自动修复(fixable)、是否提供建议(hasSuggestions)。
这些属性恰好与 ESLint 规则本身的元数据一一对应,因此rule宏在文档站点中承担着“将规则元数据可视化为结构化卡片”的职责,同时被 rules 页面(Rules Reference)批量调用以生成完整的规则索引。
二、基本用法:导入宏并传参渲染
2.1 导入宏
在任意需要渲染规则卡片的模板(.md或.njk)顶部,通过from ... import语句导入宏:
<!-- import the macro --> {% from 'components/rule.macro.html' import rule %}2.2 调用宏并传参
导入后,以对象字面量的形式向宏传入参数:
<!-- use the macro --> {{ rule({ name: "rule-name", deprecated: true, // or removed: true replacedBy: "name-of-replacement-rule", description: 'Example: Enforce `return` statements in getters.', categories: { recommended: true, fixable: true, hasSuggestions: false } }) }}注意:deprecated与removed二者通常二选一;replacedBy仅在规则被废弃或移除时才有意义;categories中的三个布尔值控制卡片右侧分类图标的显示。
三、渲染逻辑源码剖析
深入阅读 rule.macro.html 的完整实现,可以看到宏的渲染逻辑分为三大分支,对应规则的三种生命周期状态。
3.1 外层容器
宏首先输出一个<article>元素,并根据状态追加 CSS 类:
<article class="rule {% if params.deprecated == true %}rule--deprecated{% endif %} {% if params.removed == true %}rule--removed{% endif %}">也就是说,被废弃的规则卡片带有rule--deprecated样式类,被移除的规则卡片带有rule--removed样式类,前端样式层可以据此为不同状态的规则渲染不同的视觉风格。
3.2 deprecated 与 removed 分支
当deprecated == true或removed == true时,宏渲染规则名称并追加一个状态徽标(<span class="rule__status">deprecated</span>或removed):
{%- if params.deprecated == true -%} <p class="rule__name"> {{ params.name }} <span class="rule__status">deprecated</span> </p> {%- if params.replacedBy|length -%} <p class="rule__description">Replaced by {{ replacementRuleList({ specifiers: params.replacedBy }) }}</p> {%- else -%}<p class="rule__description">{{ params.description }}</p> {%- endif -%}关键细节:当存在replacedBy时,描述位置显示的是 “Replaced by ...” 的替换规则链接列表(由replacementRuleList子宏渲染),而非规则的原始描述;当没有替换规则时,才退回到params.description。这正是规则索引页对已废弃规则的统一呈现方式。
此外,被废弃/移除的规则名称不渲染为链接,因为对应的规则文档可能已不存在。
3.3 活跃规则分支
当规则既未废弃也未移除时,宏渲染一个可点击的规则名链接,指向该规则的独立文档页:
<div class="rule__name_wrapper"> <a href="{{ ['/rules/', params.name] | join | url }}" class="rule__name">{{ params.name }}</a> {%- if params.categories and params.categories.frozen %} <p class="frozen"> ❄️ <span class="visually-hidden">Frozen</span></p> {%- endif -%} </div> <p class="rule__description">{{ params.description }}</p>链接地址通过['/rules/', params.name] | join拼接为/rules/<规则名>/,经 Eleventy 的url过滤器转换为最终站点路径。例如getter-return会链接到/rules/getter-return/(对应 getter-return 规则文档)。同时,若categories.frozen为true,会在名称旁渲染雪花图标 ❄️,表示该规则已“冻结”(不再接收功能请求)。
3.4 分类图标区域
只要removed参数未被显式定义,宏就会渲染一个分类图标区rule__categories:
{%- if params.removed == undefined -%} <div class="rule__categories"> <span class="visually-hidden">Categories:</span> {%- if params.deprecated -%} <p class="rule__categories__type">❌</p> {%- else -%} <p class="rule__categories__type"{% if params.categories.recommended == false %} aria-hidden="true"{%- endif -%}> ✅ <span class="visually-hidden">Extends</span> </p> {%- endif -%} <p class="rule__categories__type"{% if params.categories.fixable == false %} aria-hidden="true"{%- endif -%}> 🔧 <span class="visually-hidden">Fix</span> </p> <p class="rule__categories__type"{% if params.categories.hasSuggestions == false %} aria-hidden="true"{%- endif -%}> 💡 <span class="visually-hidden">Suggestions</span> </p> </div> {%- endif -%}图标语义如下:
| 图标 | 含义 | 显示条件 |
|---|---|---|
| ❌ | 已废弃(deprecated) | deprecated为true |
| ✅ | 属于 recommended 配置(Extends) | recommended为true且未废弃 |
| 🔧 | 可自动修复(Fix) | fixable为true |
| 💡 | 提供编辑器建议(Suggestions) | hasSuggestions为true |
当对应分类为false时,通过aria-hidden="true"对辅助技术隐藏图标(同时配合visually-hidden提供屏幕阅读器文本),实现“该分类不适用”的无障碍表达。
四、三个开箱即用的示例
文档 docs/src/library/rule.md 给出了三种典型状态的完整调用示例,可直接复用到任意模板中。
4.1 已废弃规则:array-bracket-newline
{{ rule({ name: "array-bracket-newline", deprecated: true, description: 'Enforces line breaks after opening and before closing array brackets.', categories: { recommended: true, fixable: true, hasSuggestions: false } }) }}array-bracket-newline是一条已废弃的排版类核心规则,其替换信息记录在 docs/src/_data/rules.json 的deprecated数组中,replacedBy指向 ESLint Stylistic 生态下的同名规则。
4.2 已移除规则:no-arrow-condition
{{ rule({ name: "no-arrow-condition", removed: true, description: 'Disallows arrow functions where test conditions are expected.', replacedBy: ["no-confusing-arrow", "no-constant-condition"], categories: { recommended: false, fixable: false, hasSuggestions: false } }) }}no-arrow-condition是一条已被整体移除的历史规则,replacedBy以字符串数组形式给出两条替代规则,渲染为以 “or” 分隔的链接列表(对应代码库中的 no-confusing-arrow.js 与 no-constant-condition.js)。
4.3 活跃规则:getter-return
{{ rule({ name: "getter-return", deprecated: false, description: 'Enforce `return` statements in getters.', categories: { recommended: true, fixable: false, hasSuggestions: false } }) }}getter-return是一条仍处于活跃状态的推荐规则,完整规则文档见 getter-return.md,其实现位于 lib/rules/getter-return.js。
五、配套组件:替换规则列表与分类渲染
rule宏并非孤立工作,它与组件库中的另外两个宏协同配合。
5.1 replacementRuleList:渲染替换规则链接
rule-list.macro.html 定义了replacementRuleList宏,接受specifiers数组(元素形如{ rule: { name, url }, plugin: { name, url } }),渲染为 or 分隔的链接列表:
{{ replacementRuleList({ specifiers: [{ rule: { name: 'global-require', url: '...' }, plugin: { name: '@eslint-community/eslint-plugin-n', url: '...' } }] }) }}其实现逻辑为:
{%- macro replacementRuleList(params) -%} {% for specifier in params.specifiers %} <a href="{{ specifier.rule.url if specifier.plugin else specifier.rule.name }}" class="rule-list-item"><code>{{ specifier.rule.name }}</code></a> {% if specifier.plugin %}<span> in <a href="{{ specifier.plugin.url | url }}"><code>{{ specifier.plugin.name }}</code></a> {% endif %} {%- if loop.length > 1 and not loop.last -%} or <br />{%- endif -%} {% endfor %} {%- endmacro -%}可见:当替换规则属于某个插件(存在specifier.plugin)时,链接指向specifier.rule.url,并附加 “in 插件名” 的说明;当存在多条替换规则时,用 “or” 连接。被移除的no-arrow-condition传入的字符串数组会经数据层归一化为该宏所需的specifiers结构。
5.2 ruleCategories:分类说明块
rule-categories.macro.html 定义了ruleCategories宏及recommended、fixable、hasSuggestions、frozen四个独立短代码宏,用于在规则文档页生成带图标的分类说明块:
{{ ruleCategories({ recommended: true, fixable: true, hasSuggestions: true }) }}其输出语义为:
- ✅Recommended:使用
@eslint/js中的recommended配置会在配置文件中启用此规则; - 🔧Fixable:该规则报告的部分问题可通过
--fix命令行选项自动修复; - 💡Suggestions:该规则报告的部分问题可通过编辑器的建议(suggestions)手动修复;
- ❄️Frozen:该规则当前已冻结,不再接受功能请求。
六、数据驱动:rules 页面如何批量使用 rule 宏
rule宏在实际站点中并非手写逐一调用,而是由 rules 页面(Rules Reference,/rules/index.html)结合 docs/src/_data/rules.json 中的数据循环渲染。
页面先导入宏与数据集合:
{% from 'components/rule-categories.macro.html' import ruleCategories, recommended, fixable, hasSuggestions %} {% from 'components/rule.macro.html' import rule %}随后遍历rules.types(按类型分组的规则集合)为每条规则调用rule宏:
{{ rule({ name: name_value, deprecated: deprecated_value, description: description_value, categories: { recommended: isRecommended, fixable: isFixable, frozen: isFrozen, hasSuggestions: isHasSuggestions } }) }}对rules.deprecated(废弃规则)与rules.removed(移除规则)两组数据,则分别传入deprecated: true、replacedBy或removed: true、replacedBy渲染。
rules.json中的典型数据结构如下(截取自deprecated数组):
{ "name": "array-bracket-newline", "replacedBy": [ { "message": "ESLint Stylistic now maintains deprecated stylistic core rules.", "plugin": { "name": "@stylistic/eslint-plugin" }, "rule": { "name": "array-bracket-newline" } } ], "fixable": true, "hasSuggestions": false }由此可见,rule宏的replacedBy参数最终由rules.json中的结构化数据提供,宏只负责消费这些数据完成渲染。此外,docs/src/_data/rule_versions.json 记录了每条规则被添加的 ESLint 版本号(例如array-bracket-newline为4.0.0-alpha.1、accessor-pairs为0.22.0),供规则索引按版本筛选。
七、在文档中新增/维护规则卡片的操作指引
综合以上分析,在实际使用中可以遵循以下流程:
- 确认规则状态:判断该规则是活跃(active)、已废弃(deprecated)还是已移除(removed);
- 准备元数据:活跃规则需要
name、description与categories(recommended、fixable、frozen、hasSuggestions);废弃/移除规则需额外准备replacedBy(单条为字符串,多条为数组); - 选择渲染位置:规则索引由 rules 页面 依据
rules.json自动批量渲染,无需手工插入;在组件库演示页(如 docs/src/library/rule.md)或自定义模板中则手工调用宏; - 同步数据文件:若规则状态发生变化,需同步更新 docs/src/_data/rules.json 中的对应条目,以保证索引页与实际状态一致;
- 为活跃规则编写独立文档:在 docs/src/rules 目录下创建
<rule-name>.md,其 front matter 中的rule_type、related_rules等字段会进一步驱动规则详情页的渲染。
八、小结
rule宏是 ESLint 文档站规则体系的最小可视化单元:它把一条规则的名称、描述、生命周期状态、替换关系与分类标签封装为一个可复用的 Nunjucks 宏,配合replacementRuleList、ruleCategories两个兄弟宏以及rules.json数据层,构建出完整的规则参考页。理解它的参数模型与渲染分支,是维护 ESLint 文档、开发自定义文档组件乃至理解 ESLint 规则元数据规范的基础。
【免费下载链接】eslintFind and fix problems in your JavaScript code.项目地址: https://gitcode.com/GitHub_Trending/es/eslint
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考