news 2026/9/10 23:09:02

深入解析 ESLint 文档站的 Rule 宏组件:从参数模型到渲染实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
深入解析 ESLint 文档站的 Rule 宏组件:从参数模型到渲染实现

深入解析 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 } }) }}

注意:deprecatedremoved二者通常二选一;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 == trueremoved == 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.frozentrue,会在名称旁渲染雪花图标 ❄️,表示该规则已“冻结”(不再接收功能请求)。

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)deprecatedtrue
属于 recommended 配置(Extends)recommendedtrue且未废弃
🔧可自动修复(Fix)fixabletrue
💡提供编辑器建议(Suggestions)hasSuggestionstrue

当对应分类为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宏及recommendedfixablehasSuggestionsfrozen四个独立短代码宏,用于在规则文档页生成带图标的分类说明块:

{{ 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: truereplacedByremoved: truereplacedBy渲染。

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-newline4.0.0-alpha.1accessor-pairs0.22.0),供规则索引按版本筛选。

七、在文档中新增/维护规则卡片的操作指引

综合以上分析,在实际使用中可以遵循以下流程:

  1. 确认规则状态:判断该规则是活跃(active)、已废弃(deprecated)还是已移除(removed);
  2. 准备元数据:活跃规则需要namedescriptioncategoriesrecommendedfixablefrozenhasSuggestions);废弃/移除规则需额外准备replacedBy(单条为字符串,多条为数组);
  3. 选择渲染位置:规则索引由 rules 页面 依据rules.json自动批量渲染,无需手工插入;在组件库演示页(如 docs/src/library/rule.md)或自定义模板中则手工调用宏;
  4. 同步数据文件:若规则状态发生变化,需同步更新 docs/src/_data/rules.json 中的对应条目,以保证索引页与实际状态一致;
  5. 为活跃规则编写独立文档:在 docs/src/rules 目录下创建<rule-name>.md,其 front matter 中的rule_typerelated_rules等字段会进一步驱动规则详情页的渲染。

八、小结

rule宏是 ESLint 文档站规则体系的最小可视化单元:它把一条规则的名称、描述、生命周期状态、替换关系与分类标签封装为一个可复用的 Nunjucks 宏,配合replacementRuleListruleCategories两个兄弟宏以及rules.json数据层,构建出完整的规则参考页。理解它的参数模型与渲染分支,是维护 ESLint 文档、开发自定义文档组件乃至理解 ESLint 规则元数据规范的基础。

【免费下载链接】eslintFind and fix problems in your JavaScript code.项目地址: https://gitcode.com/GitHub_Trending/es/eslint

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 23:07:35

OpenEuler 2026安装指南与常见问题解决

1. 项目概述OpenEuler作为国产开源操作系统的代表&#xff0c;近年来在服务器、云计算和嵌入式领域获得了广泛应用。2026年发布的版本在硬件兼容性、性能优化和开发者工具链方面都有显著提升。对于初次接触这个系统的用户来说&#xff0c;掌握正确的安装方法是后续开发工作的基…

作者头像 李华
网站建设 2026/9/10 23:07:15

OI-wiki 基础算法篇:Timsort 混合稳定排序算法深度解析

OI-wiki 基础算法篇&#xff1a;Timsort 混合稳定排序算法深度解析 【免费下载链接】OI-wiki :star2: Wiki of OI / ICPC for everyone. &#xff08;某大型游戏线上攻略&#xff0c;内含炫酷算术魔法&#xff09; 项目地址: https://gitcode.com/GitHub_Trending/oi/OI-wiki…

作者头像 李华
网站建设 2026/9/10 23:06:38

Matlab汽车仿真参数代改:批量建模、寻优与实战避坑指南

干这行久了你会发现&#xff0c;汽车仿真落到实际项目里&#xff0c;最花时间的往往不是建模本身&#xff0c;而是反反复复改参数。客户抛过来一句话&#xff1a;"这个车要是换个小排量发动机&#xff0c;百公里加速还能不能进8秒&#xff1f;"或者"风阻系数从0…

作者头像 李华
网站建设 2026/9/10 23:06:25

实时数据流处理技术:Flink核心原理与生产实践

1. 实时数据流处理的核心价值与应用场景在当今这个数据爆炸的时代&#xff0c;企业每天产生的数据量已经达到了惊人的PB级别。传统批处理模式"先存储后计算"的方式&#xff0c;在面对金融交易监控、物联网设备管理、实时推荐系统等场景时显得力不从心。实时数据流处理…

作者头像 李华
网站建设 2026/9/10 23:04:40

CasADi非线性问题求解器:nlpsol

文章目录非线性求解函数约束求解求解器选择非线性求解函数 nlpsol 是 CasADi 里用来求解 非线性规划问题&#xff08;NonLinear Programming, NLP&#xff09; 的核心接口。功能很直接&#xff0c;给它一个目标函数和约束&#xff0c;它会调用优化求解器算出最优解。由于CasAD…

作者头像 李华