ESLint 插件迁移到 Flat Config从 eslintrc 到 v9 新配置体系的完整改造指南【免费下载链接】eslintFind and fix problems in your JavaScript code.项目地址: https://gitcode.com/GitHub_Trending/es/eslint从 ESLint v9.0.0 起默认配置体系已切换为新的 flat config 系统插件作者必须对现有插件做出相应调整才能在 flat config 文件中正常工作。本文以本仓库官方文档 docs/src/extend/plugin-migration-flat-config.md 为骨架结合仓库源码系统讲解插件入口结构、meta信息、规则、处理器、共享配置与环境的迁移步骤以及新旧两套配置体系并存的向后兼容方案读完即可动手改造自己的插件。为什么需要迁移flat config 带来的结构性变化在旧版 eslintrc 配置体系中ESLint 可以从插件包名中推断插件信息例如eslint-plugin-example自动对应命名空间example也可以自动应用以文件扩展名命名的处理器、直接读取environments键。而 flat config 体系的设计目标是让配置对象扁平化、显式化这些魔法行为被逐一移除ESLint 不再通过包名反查插件信息插件必须显式提供meta.name与meta.version以.md这类文件扩展名命名的处理器不再自动应用且其名称不再合法environments键在 flat config 模式下被整体忽略需转换为导出的 config插件的共享配置configs键必须从 eslintrc 格式改写为 flat config 格式。这些变化的直接后果体现在本仓库源码中在 lib/config/flat-config-schema.js 里env、extends、globals、parserOptions、overrides等 eslintrc 风格键被createEslintrcErrorSchema()包装为遇到即抛错的 schema一旦 flat config 文件中出现这些旧键校验阶段会直接抛出IncompatibleKeyError。因此迁移不是可选优化而是插件在 v9 下可用的必要步骤。推荐插件结构统一的入口对象为了让插件在 flat config 体系下获得最大灵活性官方文档建议将所有插件的入口文件统一为如下结构const plugin { meta: {}, configs: {}, rules: {}, processors: {}, }; // for ESM export default plugin; // OR for CommonJS module.exports plugin;这一结构同样也是 docs/src/extend/plugins.md 中推荐的插件组织方式。四个顶层键的职责分别是键职责迁移要求meta插件名称、版本等元信息必须新增至少含nameconfigs命名的共享配置需改写为 flat config 格式rules自定义规则定义无需任何改动processors命名处理器需补meta改名文件扩展名处理器作为参考仓库自带的示例插件 docs/_examples/custom-rule-tutorial-code/eslint-plugin-example.js 目前以module.exports plugin的形式导出rules对象其配套示例配置 docs/_examples/custom-rule-tutorial-code/eslint.config.js 可以对照查看 flat config 文件中插件的引用方式。为插件补充 meta 信息eslintrc 体系下ESLint 可以从 npm 包名提取插件信息flat config 下插件不再暴露包名因此必须在meta键中显式声明且至少包含name理想情况下同时包含versionconst plugin { meta: { name: eslint-plugin-example, version: 1.0.0, }, configs: {}, rules: {}, processors: {}, }; // for ESM export default plugin; // OR for CommonJS module.exports plugin;若插件以 npm 包形式发布meta.name与meta.version应与其package.json中的name和version保持一致否则可自行指定任意值。缺失meta的后果没有这段元信息插件将无法配合--cache与--print-config这两个命令行选项使用。前者依赖插件名称做缓存键后者需要输出包含插件信息的最终配置缺少名称都会导致功能失效。此外从源码结构看插件命名空间还承担了更多职责在 lib/config/config.js 中解析插件引用时会同时检查configPluginName与configPlugin.meta.namespace是否匹配说明meta.namespace允许用户在配置文件中给插件换命名空间时仍能被defineConfig()正确找到——这是 docs/src/extend/plugins.md 中建议在meta里补充namespace字段的原因。迁移规则Rules零改动规则部分是最轻松的迁移项。rules键在 flat config 下的工作方式与 eslintrc 完全一致插件中已有的规则定义无需任何修改。规则 ID 仍然不能包含/字符命名空间前缀如example/dollar-sign由用户在配置文件的plugins键中指定后在rules键中引用即可。迁移处理器Processors处理器迁移分两种情况1. 为每个处理器补充 meta 对象flat config 要求每个处理器附带meta对象如meta: { providesLanguages: [...] }具体字段要求可参见 custom-processors 的完整文档。2. 重命名文件扩展名处理器关键变更只要你不使用以文件扩展名命名的处理器processors键无需其他改动。但旧体系中自动按扩展名应用处理器的行为已取消以.md命名的处理器在新体系中不再合法且不会被自动应用。const plugin { configs: {}, rules: {}, processors: { // no longer supported .md: { preprocess() {}, postprocess() {}, }, }, }; // for ESM export default plugin; // OR for CommonJS module.exports plugin;必须把.md这类名称替换为合法标识符仅由数字和字母组成例如markdownconst plugin { configs: {}, rules: {}, processors: { // works in both old and new config systems markdown: { preprocess() {}, postprocess() {}, }, }, }; // for ESM export default plugin; // OR for CommonJS module.exports plugin;改名后用户必须在配置中手动指定该处理器——它不再被自动应用。下面是用defineConfig()从eslint/config导入底层实现见 lib/config-api.js显式启用的示例import { defineConfig } from eslint/config; import example from eslint-plugin-example; export default defineConfig([ { files: [**/*.md], plugins: { example, }, processor: example/markdown, }, ]);处理器名称的引用格式为命名空间/处理器名example/markdown这与 docs/src/extend/plugins.md 中处理器在配置文件中的用法一致。如果你重命名了文件扩展名处理器记得同步更新插件文档告知用户新名称及手动配置方式。迁移共享配置Configs改写为 flat config 格式如果插件导出的configs引用回插件自身就必须将其从 eslintrc 格式改写为 flat config 格式。核心变化是在配置中通过plugins键直接引用插件对象而非字符串插件名并显式声明命名空间。先看旧格式——一个名为eslint-plugin-example的插件导出的recommended配置// plugin name: eslint-plugin-example module.exports { configs: { // the config referenced by example/recommended recommended: { plugins: [example], rules: { example/rule1: error, example/rule2: error } } }, rules: { rule1: {}, rule2: {}; } };迁移到 flat config 时需要把配置的赋值移到推荐插件结构中plugin变量定义之后这样配置内才能引用plugin变量本身。使用Object.assign(plugin.configs, ...)是为了避免在对象字面量中自引用const plugin { configs: {}, rules: {}, processors: {}, }; // assign configs here so we can reference plugin Object.assign(plugin.configs, { recommended: { plugins: { example: plugin, }, rules: { example/rule1: error, example/rule2: error, }, }, }); // for ESM export default plugin; // OR for CommonJS module.exports plugin;注意plugins键从字符串数组[example]变为对象{ example: plugin }——这是 eslintrc 与 flat config 在插件引用上的最直观差异。用户随后可以这样使用导出的配置并通过extends引用、按需覆盖规则import { defineConfig } from eslint/config; import example from eslint-plugin-example; export default defineConfig([ // use recommended config and provide your own overrides { files: [**/*.js, **/*.cjs, **/*.mjs], plugins: { example, }, extends: [example/recommended], rules: { example/rule1: warn, }, }, ]);导出数组形式的 config如果某个配置需要扩展其他配置可以把多个 flat config 对象打包成数组导出const baseConfig require(./base-config); module.exports { configs: { extendedConfig: [ baseConfig, { rules: { example/rule1: error, example/rule2: error, }, }, ], }, };这与 docs/src/extend/plugins.md 中recommended配置以含单个配置对象的数组形式导出的写法一致——数组中的多个对象会依次合并生效。迁移后记得更新插件文档让用户了解如何引用新的导出的 config。迁移环境Environments转为导出的 configenvironments在 flat config 中已不再被支持官方推荐将其转换为导出的 config。核心映射规则是环境里的globals移入 flat config 的languageOptions.globals且全局变量取值从 eslintrc 的布尔值true表示只读变为 flat config 的字符串readonly、writeable等。以导出mocha环境为例旧格式如下// plugin name: eslint-plugin-example module.exports { environments: { mocha: { globals: { it: true, xit: true, describe: true, xdescribe: true } } }, rules: { rule1: {}, rule2: {}; } };迁移后在plugin.configs中新增一个包含相同信息的 flat config 对象const plugin { configs: {}, rules: {}, processors: {}, }; // assign configs here so we can reference plugin Object.assign(plugin.configs, { mocha: { languageOptions: { globals: { it: writeable, xit: writeable, describe: writeable, xdescribe: writeable, }, }, }, }); // for ESM export default plugin; // OR for CommonJS module.exports plugin;注意文档示例中it等全局变量使用writeable即旧 eslintrc 中true的含义这是 ESLint 官方文档沿用的拼写按 flat config 规范可写取值为writable实际书写时两种拼写语义相同均表示可写。用户通过extends引用该配置并在自己的languageOptions.globals中覆盖默认值import { defineConfig } from eslint/config; import example from eslint-plugin-example; export default defineConfig([ { files: [**/tests/*.js], plugins: { example, }, // use the mocha globals extends: [example/mocha], // and provide your own overrides languageOptions: { globals: { it: readonly, }, }, }, ]);这里体现了 flat config 的合并语义extends引入的配置与当前配置对象合并时当前配置中的languageOptions.globals会覆盖mocha配置中的同名键把it从可写降级为只读。迁移后同样要更新插件文档告知用户新的引用方式。向后兼容同时支持新旧两套配置体系如果你的插件仍需兼容旧版 eslintrc 体系需要同时做到以下三点导出 CommonJS 入口。旧配置体系无法加载仅以 ESM 格式发布的插件。若源码是 ESM需要用打包器生成 CommonJS 版本并在package.json的exports键中配置入口映射确保 Node.js 能按模块格式找到对应版本。保留environments键。若插件导出自定义环境应原样保留供 eslintrc 用户使用同时按上文方式导出等价的 flat config。当 ESLint 运行在 flat config 模式下时environments键会被直接忽略——这从 lib/config/flat-config-schema.js 的eslintrcKeys列表也能印证env是遇到即抛错的旧键而插件对象的environments在 flat config 模式下不被读取。同时导出 eslintrc 与 flat config 两种格式的 configs。configs键只有在某个配置被实际使用时才被校验因此可以在同一个configs键下同时提供两种格式。官方建议旧格式配置加legacy-前缀例如legacy-recommended如果不想改原名也可以在configs中新增flat/前缀的条目例如flat/recommended。关于第 3 点的命名策略docs/src/extend/plugins.md 有更完整的示例同一插件可在configs中同时放置 flat 格式的flat/recommended和 eslintrc 格式的recommended。其背后机制是defineConfig()助手会先查找recommended键若该键不是 flat config 格式再回退查找flat/recommended键——这为将来彻底放弃旧体系后把flat/recommended改名为recommended预留了平滑升级路径。迁移清单与关键要点迁移项操作注意事项入口结构统一为{ meta, configs, rules, processors }并默认导出ESM 用export defaultCJS 用module.exportsmeta新增name必须、version推荐、namespace推荐缺失会导致--cache与--print-config失效rules无需改动规则 ID 仍不能含/processors补充meta重命名扩展名处理器.md等名称非法且不再自动应用需手动在配置中指定configs改写为 flat configplugins用对象形式直接引用插件多配置合并可导出数组environments转为configs中的 flat configglobals布尔值改为readonly/writeable字符串flat config 模式下environments被忽略双体系兼容CJS 入口、保留environments、双格式 configs旧格式建议加legacy-前缀或新增flat/前缀条目延伸阅读插件开发完整指南含meta.namespace、flat/前缀与双格式 configs 详解自定义处理器文档自定义规则教程含插件示例代码flat config 体系的设计背景与 API 用法可参阅仓库 docs/src/extend/index.md 中列出的扩展指南以及仓库内其余 extend 文档目录下的相关主题【免费下载链接】eslintFind and fix problems in your JavaScript code.项目地址: https://gitcode.com/GitHub_Trending/es/eslint创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考