资讯动态

ESLint 核心规则贡献完全指南:从文件结构、单元测试到性能验证与冻结规则约定

发布时间:2026/9/11 18:52:12 来源:尧图企业网站定制
ESLint 核心规则贡献完全指南从文件结构、单元测试到性能验证与冻结规则约定【免费下载链接】eslintFind and fix problems in your JavaScript code.项目地址: https://gitcode.com/GitHub_Trending/es/eslint本篇技术指南以 ESLint 官方贡献文档 docs/src/contribute/core-rules.md 为核心骨架完整讲解核心规则Core Rules的定义、三文件结构、源码编写格式、RuleTester单元测试、npm run perf性能验证、命名约定以及「冻结规则」Frozen Rules机制并结合本仓库中的真实源码如 lib/rules/no-extra-semi.js、tests/lib/rules/no-extra-semi.js逐层印证。读完本文你将掌握向 ESLint 仓库提交一条合格核心规则所需的全部规范与可落地步骤。什么是 ESLint 核心规则ESLint 的核心规则Core Rules是指随eslint包一起发布的、内置于 ESLint 中的规则集合分布在仓库的 lib/rules 目录下共 300 余条例如no-extra-semi、semi、no-eval等。与之相对的是由插件提供的自定义规则Custom Rules。核心规则与自定义规则使用完全相同的 API——两者的规则模块都导出meta元数据对象与create访客函数底层由Linter统一调度。核心规则与自定义规则的主要区别只有两点核心规则随eslint包分发无需额外安装插件即可使用核心规则必须遵守本文档docs/src/contribute/core-rules.md所记录的仓库级约定。规则编写的完整参考请见 Custom Rules 文档其中详细规定了meta含type、docs、fixable、hasSuggestions、schema、defaultOptions、languages、deprecated等、create()访问器、context对象、context.report()问题上报、fix自动修复与suggest建议等全部细节核心规则与自定义规则遵循同一套格式。核心规则的三文件结构每个核心规则都对应三个同名文件以规则标识符如no-extra-semi命名位置用途以no-extra-semi为例lib/rules/下的源码文件规则实现lib/rules/no-extra-semi.jstests/lib/rules/下的测试文件规则单元测试tests/lib/rules/no-extra-semi.jsdocs/src/rules/下的文档文件规则使用文档docs/src/rules/no-extra-semi.md重要若向 ESLint 仓库提交一条核心规则必须同时提供上述三个文件并遵守下列全部约定。规则文档文件的格式要求docs/src/rules/下的文档使用 Markdown 编写文件头以 YAML front matter 声明元信息例如 docs/src/rules/no-extra-semi.md 的开头--- title: no-extra-semi rule_type: suggestion related_rules: - semi - semi-spacing ---其中rule_type必须与源码meta.type一致problem/suggestion/layoutrelated_rules列出相关规则便于文档交叉引用。正文使用::: incorrect/::: correct等容器分别展示该规则的错误示例与正确示例。核心规则源码的基本格式官方文档给出了核心规则源码文件的基本骨架本节将其与仓库真实实现对照解读。官方模板/** * fileoverview Rule to disallow unnecessary semicolons * author Nicholas C. Zakas */ use strict; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ /** type {import(../types).Rule.RuleModule} */ module.exports { meta: { type: suggestion, docs: { description: disallow unnecessary semicolons, recommended: true, url: https://eslint.org/docs/rules/no-extra-semi, }, fixable: code, schema: [], // no options }, create: function (context) { return { // callback functions }; }, };模板要点文件头使用fileoverview描述规则用途、author标注作者通过/** type {import(../types).Rule.RuleModule} */进行 JSDoc 类型标注该类型定义在 lib/types/index.d.ts 中meta.docs.description是核心规则的必填项用于生成 rules index 规则索引meta.fixable只能取code或whitespace且可修复规则必须声明否则 ESLint 会在规则尝试产生修复时抛错meta.schema用于校验规则配置项无选项时写schema: []此时用户传入任何选项都会被判定为非法。真实实现no-extra-semi的结构解读查看仓库中 lib/rules/no-extra-semi.js可以看到一条成熟核心规则的完整形态。其meta部分lib/rules/no-extra-semi.js#L22-L58包含meta: { deprecated: { message: Formatting rules are being moved out of ESLint core., url: https://eslint.org/blog/2023/10/deprecating-formatting-rules/, deprecatedSince: 8.53.0, availableUntil: 11.0.0, replacedBy: [ { message: ESLint Stylistic now maintains deprecated stylistic core rules., url: https://eslint.style/guide/migration, plugin: { name: stylistic/eslint-plugin, url: https://eslint.style }, rule: { name: no-extra-semi, url: https://eslint.style/rules/no-extra-semi }, }, ], }, type: suggestion, docs: { description: Disallow unnecessary semicolons, recommended: false, url: https://eslint.org/docs/latest/rules/no-extra-semi, }, fixable: code, schema: [], messages: { unexpected: Unnecessary semicolon., }, },对比模板可以发现几个核心规则进阶要点messages对象集中管理违规消息通过messageId在context.report()中引用此例为unexpected避免消息文本在规则文件与测试文件中重复deprecated结构声明规则的废弃状态、废弃起始版本、可用截止版本以及替代方案replacedBydocs.recommended标识该规则是否被eslint/js的recommended配置默认启用。create部分lib/rules/no-extra-semi.js#L60-L166通过注册EmptyStatement、ClassBody、MethodDefinition, PropertyDefinition, StaticBlock等 AST 访客来识别多余分号并使用context.report()配合fix函数上报可自动修复的问题其中还通过FixTracker.retainSurroundingTokens扩大替换范围以避免与semi规则的修复冲突——这正是「核心规则修复必须小而安全」的典型实践。核心规则的单元测试每一条随包发布的核心规则都必须附带单元测试才能被接收。测试文件与源码文件同名放在tests/lib/rules/目录下若规则源码为lib/rules/foo.js则测试文件应为tests/lib/rules/foo.js。ESLint 提供了RuleTester工具让规则测试的编写变得非常简单。该工具由 lib/rule-tester/rule-tester.js 实现内部基于 Mocha/Jest 的describe/it框架封装见 lib/rule-tester/rule-tester.js#L1-L37。以 tests/lib/rules/no-extra-semi.js 为例真实测试骨架如下const rule require(../../../lib/rules/no-extra-semi), RuleTester require(../../../lib/rule-tester/rule-tester); const ruleTester new RuleTester({ languageOptions: { ecmaVersion: 5, sourceType: script, }, }); ruleTester.run(no-extra-semi, rule, { valid: [ var x 5;, for(;;);, { code: for(a of b);, languageOptions: { ecmaVersion: 6 } }, { code: class A { }, languageOptions: { ecmaVersion: 6 } }, ], invalid: [ { code: var x 5;;, output: var x 5;, errors: [{ messageId: unexpected }], }, { code: class A { static { ; } }, output: class A { static { } }, languageOptions: { ecmaVersion: 2022 }, errors: [{ messageId: unexpected, column: 20 }], }, // 断言 output: null —— 期望规则报告问题但不提供自动修复 { code: ; use strict, output: null, errors: [{ messageId: unexpected }] }, ], });RuleTester的关键使用规则根据 RuleTester 文档ruleTester.run(name, rule, tests)接收三个参数规则名称、规则对象、以及包含valid与invalid两个数组的测试对象可选传assertionOptions如requireMessage: true对invalid用例的断言一致性做强制约束valid数组中的字符串表示该代码不应触发任何报告对象形式可附加options、languageOptions、settings、filename、before/after等属性invalid数组中的每个用例必须声明errors可指定message字符串、正则表达式或messageId并可用line、column精确断言位置output表示自动修复后的期望代码当output为null时表示断言「该问题没有自动修复」这正是no-extra-semi在; use strict场景下的行为——移除分号会使后续字符串语句变成指令directive因此不能自动修复RuleTester构造函数不传参时使用 ESLint 默认值languageOptions: { ecmaVersion: latest, sourceType: module }也可通过静态方法RuleTester.setDefaultConfig(config)、RuleTester.getDefaultConfig()、RuleTester.resetDefaultConfig()批量管理默认配置。运行测试可使用仓库根目录 package.json 中定义的脚本npm test实际执行node Makefile.js test它会在 CI 与本地对全部核心规则测试文件进行跑批。性能测试用npm run perf验证规则开销为了保持 lint 过程的效率与低侵入性新规则或对现有规则的改动都应验证其性能影响。如何对单条规则进行剖析可参考 Profile Rule Performance 章节——通过设置TIMING环境变量在 lint 完成后展示运行时间最长的十条规则及其占比例如$ TIMING1 eslint lib Rule | Time (ms) | Relative :-----------------------|----------:|--------: no-multi-spaces | 52.472 | 6.1% camelcase | 48.684 | 5.7%要单独测试某条规则可组合--no-config-lookup与--rule选项将TIMING设为更大的数值如TIMING50或TIMINGall可查看更长列表。而在核心仓库内部开发时npm run perf命令会给出开启全部核心规则后 ESLint 总运行时间的高层概览该目标定义在仓库根目录 Makefile.js 中其实现会用到hyperfine等基准工具做回归对比。官方文档建议的对比流程如下$ git checkout main Switched to branch main $ npm run perf CPU Speed is 2200 with multiplier 7500000 Performance Run #1: 1394.689313ms Performance Run #2: 1423.295351ms Performance Run #3: 1385.09515ms Performance Run #4: 1382.406982ms Performance Run #5: 1409.68566ms Performance budget ok: 1394.689313ms (limit: 3409.090909090909ms) $ git checkout my-rule-branch Switched to branch my-rule-branch $ npm run perf CPU Speed is 2200 with multiplier 7500000 Performance Run #1: 1443.736547ms Performance Run #2: 1419.193291ms Performance Run #3: 1436.018228ms Performance Run #4: 1473.605485ms Performance Run #5: 1457.455283ms Performance budget ok: 1443.736547ms (limit: 3409.090909090909ms)使用要点先在main分支跑一次基线再切换到自己的规则分支跑一次对比多次运行官方示例为 5 次的平均耗时输出中的Performance budget ok表示耗时未超出基于 CPU 速度折算的预算上限示例中 limit 为3409.09ms仓库会计算 CPU 速度并乘以 multiplier 折算成预算因此不同机器上的数字不可直接横向比较应以同机同环境的基线为准。核心规则命名约定ESLint 核心规则命名遵循以下约定单词之间使用**连字符dash**分隔如no-extra-semi、no-eval若规则仅用于禁止某类写法必须以no-前缀命名例如用no-eval禁止eval()、用no-debugger禁止debugger若规则用于强制要求某类写法则使用不带特殊前缀的简短名称例如semi、quotes、curly。这套命名约定同样适用于自定义规则建议自定义规则也遵循它便于使用者理解规则意图。冻结规则Frozen Rules当规则达到功能完备feature complete状态时会被标记为冻结在文档中用 ❄️ 表情指示可在规则源码的meta.docs中找到对应标记例如 lib/rules/arrow-body-style.js 声明了frozen: true。冻结的判定标准规则被视为功能完备的标准是规则的目标用途已被完整实现能捕获 80% 及以上预期违规并覆盖绝大多数常见例外场景。在此之后若遇到未被覆盖的边缘情况官方期望用户改用禁用注释disable comments来处理而不是要求规则继续扩张。冻结意味着什么当一条规则被冻结后维护策略为Bug 修复仍会修复被确认的 bug新 ECMAScript 特性保证与新语法兼容即规则不会在新语法上崩溃TypeScript 支持保证与 TypeScript 语法兼容不会在 TS 语法上出错且对 TS 的违规判定保持恰当新选项不再新增任何选项除非新增选项是修复 bug 或支持新增 ECMAScript 特性的唯一途径。冻结规则的替代方案如果你认为某条冻结规则在你的场景下稍作改动会更好用官方推荐的做法是复制该规则源码到自己的项目中按需修改后使用。这正好呼应了 Custom Rules 文档中的警告——eslint包中内置的核心规则不属于公共 API不适合被直接继承扩展基于核心规则二次开发非常脆弱未来很可能因内部变化而彻底失效因此应优先复制源码再改造。提交核心规则前 Checklist综合官方文档与仓库实际向 ESLint 仓库提交一条核心规则前请逐项核对三文件齐全lib/rules/rule-id.js源码、tests/lib/rules/rule-id.js测试、docs/src/rules/rule-id.md文档三者命名一致源码格式合规文件头fileoverview/author、use strict、JSDoc 类型标注Rule.RuleModule、meta中type/docs.description/schema齐全可修复规则声明fixable可修复的messageId收拢在meta.messages中测试覆盖充分使用RuleTester提供valid与invalid两组用例覆盖常见正确/错误代码、语法版本边界如 ES6 class、ES2022 静态块以及「不可自动修复」场景output: null性能验证使用npm run perf在main与规则分支间对比总运行时间确认未突破性能预算命名与状态遵循连字符命名与no-前缀约定评估规则是否已达功能完备而可标记frozen: true并遵守冻结规则不新增选项的约定。按此清单推进你的规则就能与仓库中现有 300 余条核心规则保持一致的工程质量顺利进入审查与合并流程。【免费下载链接】eslintFind and fix problems in your JavaScript code.项目地址: https://gitcode.com/GitHub_Trending/es/eslint创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价