ESLint 配置组合实战用extends合并配置对象与配置数组【免费下载链接】eslintFind and fix problems in your JavaScript code.项目地址: https://gitcode.com/GitHub_Trending/es/eslint在实际项目中eslint.config.js很少完全从零手写你通常会将社区预定义配置、可共享配置shareable config与自己的覆写规则组合在一起形成项目专属的 ESLint 配置。本文围绕 docs/src/use/configure/combine-configs.md 讲解的两种核心组合模式——应用配置对象与应用配置数组——展开并结合当前仓库源码说明extends键在 flat config 体系下的求值顺序、合并语义与底层实现让你能正确、灵活地组装自己的配置文件。前置概念配置对象与配置数组在理解组合之前需要先明确两个基础概念详见 glossary 术语表配置对象Config Object一个包含files、plugins、rules、languageOptions等键的普通对象描述了 ESLint 在满足某些条件时如何解析与检查文件。配置数组Config Array配置对象的数组。eslint.config.js导出的就是一个配置数组。数组内的对象按顺序求值后面的对象可以覆盖前面对象中同名规则的设置——这正是 flat config 区别于旧 eslintrcextends深层合并的关键语义。每个配置文件都导出配置数组例如下面这份只含一个配置对象的配置来自 configuration-files.md 的示例// eslint.config.js import { defineConfig } from eslint/config; export default defineConfig([ { rules: { semi: error, prefer-const: error, }, }, ]);这里的defineConfig()是eslint/config提供的辅助函数它的作用仅仅是让编辑器获得更好的类型提示与自动补全其返回值仍是一个配置数组与直接写数组字面量等价。defineConfig与eslint/config入口在 lib/config-api.js 中可以看到eslint/config模块的真实导出const { defineConfig, globalIgnores, includeIgnoreFile, } require(eslint/config-helpers); module.exports { defineConfig, globalIgnores, includeIgnoreFile, };也就是说eslint/config对外提供了三个辅助函数defineConfig定义配置数组、globalIgnores全局忽略、includeIgnoreFile引入.gitignore等忽略文件。它们均来自eslint/config-helpers包ESLint 只是将其重新导出方便统一从eslint/config引入。组合配置时我们主要使用defineConfig包裹整个配置数组。模式一应用一个配置对象filesextends当从其他模块导入一个配置对象时可以创建一个带files键的新对象并通过extends键把导入对象的其余属性合并进来从而让该配置只作用于文件子集。// eslint.config.js import js from eslint/js; import { defineConfig } from eslint/config; export default defineConfig([ { files: [**/*.js], plugins: { js, }, extends: [js/recommended], rules: { no-unused-vars: warn, }, }, ]);这段配置的含义是files: [**/*.js]限定本配置对象只作用于所有.js文件extends: [js/recommended]将eslint/js包内置的recommended预定义配置一个配置对象合并进来。当前仓库中该预定义配置定义在 packages/js/src/index.jsconfigs: { all: require(./configs/eslint-all), recommended: require(./configs/eslint-recommended), },rules: { no-unused-vars: warn }在合并后的基础上追加规则覆写。由于files与extends位于同一个对象内合并后的完整配置预定义配置的规则 你自己的覆写只会应用到**/*.js匹配的文件上。这是先限定文件范围、再注入预定义配置的标准写法。为什么要显式声明plugins注意上面的示例在extends之外还显式声明了plugins: { js }。原因是在 flat config 中规则所属的插件必须在每个使用它的配置对象里可见。extends合并进来的是eslint/js内部的规则定义而js/recommended这样的引用字符串最终要解析为某个已注册插件下的规则集。保持插件对象与配置对象同处一个作用域可以让合并与后续校验见下文Config类顺利进行。这是从当前仓库 Config 类的规则解析逻辑 可以观察到的约束规则 ID 中的插件名会通过config.plugins查找对应插件。模式二应用一个配置数组extends数组当从其他模块导入的是一个配置数组时同样可以通过extends键把它应用到文件子集。例如从eslint-config-example包导入配置// eslint.config.js import exampleConfigs from eslint-config-example; import { defineConfig } from eslint/config; export default defineConfig([ { files: [**/*.js], extends: [exampleConfigs], rules: { no-unused-vars: warn, }, }, ]);这里extends: [exampleConfigs]传入的是一个配置数组数组中每个元素是配置对象。行为与模式一完全一致exampleConfigs中的全部配置对象先被展开合并然后rules中的no-unused-vars: warn作为后续配置对象追加覆盖。两种模式的本质区别对比维度模式一应用配置对象模式二应用配置数组extends中的元素类型配置对象或引用该对象的字符串如js/recommended配置对象、配置数组或引用它们的字符串典型来源eslint/js、eslint-plugin-*导出的单个对象可共享配置包导出的数组应用范围受外层files约束受外层files约束行为一致事实上两种模式在底层走的是同一条路径extends接受字符串、配置对象或配置数组构成的列表这些元素会被依次展开后与当前对象的files合并。这与 configuration-files.md 中对extends键的官方定义一致extends- An array of strings, configuration objects, or configuration arrays that contain additional configuration to apply.合并语义数组按序求值后者覆盖前者理解组合配置最关键的一点是合并顺序。在 flat config 中配置数组内的对象按顺序求值对于规则配置后出现的对象会覆盖override先前对象中同名规则的设置对于数组型配置如languageOptions的某些字段则按deepMergeArrays的策略合并——该实现位于 lib/shared/deep-merge-arrays.jsConfig类构造时引入。以一个三段式配置为例export default defineConfig([ { files: [**/*.js], extends: [js/recommended], }, { files: [**/*.js], rules: { no-unused-vars: warn, // 覆盖 recommended 中该规则的默认级别 }, }, { files: [**/*.test.js], rules: { no-unused-vars: off, // 测试文件里彻底关闭 }, }, ]);第一段注入js/recommended第二段把no-unused-vars调整为warn第三段只对测试文件关闭该规则。这正是预定义配置 项目覆写 文件子集特例的典型三段式结构也是extends组合模式最常见的实际用法。底层机制FlatConfigArray与Config类的处理流程组合配置在运行时经历两个关键阶段对应仓库源码展开与合并配置文件导出的数组被包装成 FlatConfigArray继承自eslint/config-array的ConfigArray。其中的preprocessConfig钩子lib/config/flat-config-array.js#L182-L202负责把extends中的字符串与数组元素替换为真实对象后再进入规范化流程。校验与规范化每个合并完成的配置对象交由 Config 类 处理用ObjectSchema(flatConfigSchema)校验键的合法性、解析language与processor、合并languageOptions最后通过#normalizeRulesConfig与validateRulesConfiglib/config/config.js#L608-L633统一规则配置格式——例如把warn规范化为数字1并依据规则的meta.schema校验选项。这也解释了为什么extends合并进来的规则在运行前就会被严格校验拼写错误的规则名会直接抛出带插件提示的TypeError。与 eslintrcextends的差异如果你熟悉旧的 eslintrc 配置体系需要特别注意flat config 中extends的行为与 eslintrc 时代的继承链 深层对象合并完全不同——这里不存在递归继承的层级只有同一数组内对象的顺序覆盖。旧式 eslintrc 的env、globals、ignorePatterns、overrides等键在 flat config 中均为非法键见 flat-config-schema.js 中的 eslintrcKeys 清单extends本身也在其中被列为 eslintrc 风格、应替换为 flat config 写法的键。组合配置的进阶实战模式基于上述两条核心模式可以组合出更复杂的实战写法1多个预定义配置叠加并分别限定文件范围import js from eslint/js; import ts from typescript-eslint; import { defineConfig } from eslint/config; export default defineConfig([ { files: [**/*.js], extends: [js/recommended], }, { files: [**/*.ts], extends: [...ts.configs.recommended], }, ]);2命名配置对象便于排查与调试export default defineConfig([ { name: project/javascript, files: [**/*.js], extends: [js/recommended], rules: { no-unused-vars: warn }, }, ]);name是配置对象的可选元信息运行eslint --print-config或使用调试工具时可以据此快速定位是哪一段配置影响了文件。3配合globalIgnores组织全局忽略import { defineConfig, globalIgnores } from eslint/config; export default defineConfig([ { files: [**/*.js], extends: [js/recommended], }, globalIgnores([dist/**, node_modules/**]), ]);globalIgnores()生成一个只含ignores的配置对象其模式会对所有其他配置对象生效——这正是在 lib/config-api.js 中重新导出的辅助函数之一可作为组合配置的补充模块。常见陷阱与排查建议extends元素类型错误extends只接受字符串、配置对象或配置数组。直接传入函数、Promise等会在校验阶段被ObjectSchema拒绝报错信息会指明非法键。漏声明插件当extends引用的字符串如js/recommended所依赖的插件对象没有在当前配置对象的plugins中注册时运行时会在 Config 类的规则查找逻辑 处抛出Key rules: Key xxx: Could not find plugin类错误并提示可能的拼写或插件名。覆盖顺序反了想覆写预定义配置的规则覆写对象必须排在extends所在对象之后或与extends同处一个对象、位于其后否则会被预定义配置反覆盖。调试手段使用npx eslint --print-config file查看某个文件最终生效的合并结果或借助--debug输出配置解析过程都可以快速确认组合是否正确。小结组合配置是 flat config 体系下日常开发最常用的能力通过files限定作用范围、用extends注入预定义或可共享的配置对象/数组、再叠加自己的规则覆写即可拼装出结构清晰、按文件类型差异化的完整配置。其底层由 FlatConfigArray 负责展开合并、Config 负责规范化与校验理解这两层的求值顺序与校验时机你就能避免绝大多数配置组合过程中的灵异问题。【免费下载链接】eslintFind and fix problems in your JavaScript code.项目地址: https://gitcode.com/GitHub_Trending/es/eslint创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考