
ESLint Flat Config 插件配置完全指南从安装到 processor、language 的实战用法【免费下载链接】eslintFind and fix problems in your JavaScript code.项目地址: https://gitcode.com/GitHub_Trending/es/eslint本篇指南聚焦 ESLint 的 flat config 配置体系中插件plugins的完整配置方法如何通过plugins键引入第三方插件与本地插件、如何按命名空间引用插件规则、如何借助处理器processor检查 Markdown 等非 JavaScript 文件、以及如何为 JSON 等语言指定自定义 language。读完本文你将能独立在eslint.config.js中组织插件、规则、处理器与语言配置并结合源码理解 ESLint 底层是如何解析与合并这些配置项的。插件能为 ESLint 扩展什么在 ESLint 中插件是扩展核心能力的主要手段。插件本质上是一个“符合 ESLint 识别接口的对象”它可以包含三类可扩展内容自定义规则Custom rules校验你的代码是否满足某项预期以及不满足时如何处理例如no-console这类规则就是由插件规则扩展而来的。自定义配置Custom configurations插件内预置的一组配置如recommended具体用法请以插件自身文档为准。自定义处理器Custom processors从其他类型的文件中提取 JavaScript 代码或在 lint 之前对代码做预处理例如从.md中提取代码块。从插件对象的接口定义看参见 docs/src/extend/plugins.md一个标准插件通常导出如下结构的对象const plugin { meta: {}, // 插件元信息name、version、namespace configs: {}, // 插件内置的命名配置 rules: {}, // 自定义规则定义 processors: {}, // 命名处理器 }; // ESM export default plugin; // 或 CommonJS module.exports plugin;仓库自带的插件示例docs/_examples/custom-rule-tutorial-code/eslint-plugin-example.js就是最精简的形态const plugin { rules: { enforce-foo-bar: fooBarRule } }仅暴露一条规则。下面我们重点讲解配置端如何使用这些插件。配置插件plugins键与命名空间要在配置文件flat config 格式的eslint.config.js中启用插件需要使用plugins键。它是一个对象属性名代表插件的命名空间namespace属性值就是插件对象本身。// eslint.config.js import example from eslint-plugin-example; import { defineConfig } from eslint/config; export default defineConfig([ { plugins: { example, }, rules: { example/rule1: warn, }, }, ]);命名约定为插件创建命名空间时惯例是去掉 npm 包名中的eslint-plugin-前缀。例如eslint-plugin-example的命名空间就是example。底层校验plugins 必须是对象从源码看lib/config/flat-config-schema.jspluginsSchema对plugins值做了严格校验值必须是对象如果是数组则会抛出IncompatiblePluginsError提示“这看起来是 eslintrc 格式字符串数组而非 flat config 格式对象”每个命名空间下的值也必须是对象合并时如果两个配置对象试图用不同的插件对象重定义同一个命名空间会抛出Cannot redefine plugin xxx错误——这是 flat config 避免插件冲突的关键机制。也就是说flat config 不再像旧的 eslintrc 那样通过plugins: [example]字符串数组声明插件而是直接传入插件对象本身规则名中的example/前缀因此可以与对象直接对应。配置本地插件插件不一定要发布到 npm。你可以直接从本地文件加载插件// eslint.config.js import local from ./my-local-plugin.js; import { defineConfig } from eslint/config; export default defineConfig([ { plugins: { local, }, rules: { local/rule1: warn, }, }, ]);这里使用了命名空间local你可以换成任意喜欢的名字。本地插件的价值在于团队内部的专用规则无需发布直接通过相对路径引入即可配合下文“虚拟插件”甚至可以做到零文件组织的即时规则启用。配置虚拟插件插件定义可以直接在配置中“虚拟”创建。假设你有一个位于./rules/my-rule.js的规则文件想直接在配置里启用它可以把它包装成一个虚拟插件// eslint.config.js import myRule from ./rules/my-rule.js; import { defineConfig } from eslint/config; export default defineConfig([ { plugins: { local: { rules: { my-rule: myRule, }, }, }, rules: { local/my-rule: warn, }, }, ]);这里命名空间local定义了一个虚拟插件规则myRule在虚拟插件的rules对象中被命名为my-rule规则名中不能包含/。随后即可用local/my-rule引用并配置它。插件的完整对象格式可参考 docs/src/extend/plugins.md。使用插件规则启用插件后就可以使用插件自带的规则。规则名采用命名空间/规则名的格式前缀部分表明规则来自哪个插件而非 ESLint 内置规则。以 JSDoc 插件为例// eslint.config.js import jsdoc from eslint-plugin-jsdoc; import { defineConfig } from eslint/config; export default defineConfig([ { files: [**/*.js], plugins: { jsdoc: jsdoc, }, rules: { jsdoc/require-description: error, jsdoc/check-values: error, }, }, ]);因为插件名与对象名恰好都是jsdoc可以简写为import jsdoc from eslint-plugin-jsdoc; import { defineConfig } from eslint/config; export default defineConfig([ { files: [**/*.js], plugins: { jsdoc, }, rules: { jsdoc/require-description: error, jsdoc/check-values: error, }, }, ]);自定义命名空间前缀虽然同名是最常见惯例但并非强制。你可以为插件指定任意前缀例如把eslint-plugin-jsdoc命名为jsdimport jsdoc from eslint-plugin-jsdoc; import { defineConfig } from eslint/config; export default defineConfig([ { files: [**/*.js], plugins: { jsd: jsdoc, }, rules: { jsd/require-description: error, jsd/check-values: error, }, }, ]);此时规则引用前缀也要同步改为jsd/。注意规则配置的严重度支持off、0、warn、1、error、2六种取值lib/config/flat-config-schema.js 中的ruleSeverities映射配置错误会抛出invalid-rule-options或invalid-rule-severity错误。命名空间格式限制从源码docs/src/extend/plugins.md可知命名空间有不带与带两种规则不以开头的命名空间不能包含/如eslint/plugin非法以开头的命名空间可以包含/如eslint/plugin合法。这一限制是为了兼容旧 eslintrc 的插件命名规则。底层assertIsPluginMemberNamelib/config/flat-config-schema.js用正则[\w\-$](?:\/[\w\-$])校验插件名/成员名的格式。指定处理器Processor插件还可以提供处理器processor。处理器的两种能力提取从其他类型的文件中提取 JavaScript 代码交给 ESLint 检查如从 Markdown 提取代码块预处理在 lint 之前对 JavaScript 代码做转换。在配置文件中使用processor键值格式为命名空间/处理器名。下面用eslint/markdown对*.md文件启用markdown/markdown处理器// eslint.config.js import markdown from eslint/markdown; import { defineConfig } from eslint/config; export default defineConfig([ { files: [**/*.md], plugins: { markdown, }, processor: markdown/markdown, }, ]);处理器与命名代码块处理器可能会产出命名代码块例如0.js、1.js。ESLint 会把这样的代码块当作原文件的子文件来处理你可以用额外的配置对象对它们做精细化设置。例如对所有 JavaScript 文件开启strict规则但关闭 Markdown 内 JS 代码块的strict// eslint.config.js import markdown from eslint/markdown; import { defineConfig } from eslint/config; export default defineConfig([ // 应用于所有 JavaScript 文件 { rules: { strict: error, }, }, // 应用于 Markdown 文件 { files: [**/*.md], plugins: { markdown, }, processor: markdown/markdown, }, // 仅应用于 Markdown 文件内部的 JavaScript 代码块 { files: [**/*.md/*.js], rules: { strict: off, }, }, ]);注意**/*.md/*.js这种“斜杠嵌套”的 glob 模式正是用来匹配“Markdown 文件内名为.js的代码块”的。关键限制ESLint 只检查命名代码块且仅在它是 JavaScript 文件、或与某个配置对象的files条目匹配时才进行 lint。如果要检查非 JavaScript 的命名代码块必须额外添加带匹配files条目的配置对象。同时全局忽略规则同样适用于命名代码块。下面是另一个实战示例为 Markdown 内的 JSX 代码块开启 JSX 语法同时忽略test.md文件内的 JSX 代码块// eslint.config.js import markdown from eslint/markdown; import { defineConfig } from eslint/config; export default defineConfig([ // 应用于 Markdown 文件 { files: [**/*.md], plugins: { markdown, }, processor: markdown/markdown, }, // 应用于所有 .jsx 文件包括 Markdown 文件内部的 jsx 代码块 { files: [**/*.jsx], languageOptions: { parserOptions: { ecmaFeatures: { jsx: true, }, }, }, }, // 忽略 test.md 文件内部的 jsx 代码块 { ignores: [**/test.md/*.jsx], }, ]);处理器源码层面的执行机制从源码lib/services/processor-service.js可以印证处理器的调用链ProcessorService.preprocessSync(file, config)会调用processor.preprocess(file.rawBody, file.path)得到代码块数组再对每个块构造“子文件”path.join(file.path, \${i}_${block.filename})即原路径/序号_块名的形式lint 完成后postprocessSync会把所有子文件的 lint 消息合并交回processor.postprocess(messages, file.path)做最终汇总。这解释了为什么代码块匹配模式是**/.md/.js——子文件的路径就是在原路径下以/ 拼接块名的。同时processorSchemalib/config/flat-config-schema.js要求若processor直接传对象则该对象必须同时具备preprocess()与postprocess()方法传字符串时则按插件名/处理器名格式校验。指定语言Language插件还可以提供语言支持language让 ESLint 检查 JavaScript 之外的语言。在配置文件中使用language键值格式为命名空间/语言名。例如用eslint/json的json/jsonc语言检查*.json文件// eslint.config.js import json from eslint/json; import { defineConfig } from eslint/config; export default defineConfig([ { files: [**/*.json], plugins: { json, }, language: json/jsonc, }, ]);注意当你在配置对象中指定了language后languageOptions就会变得与这种语言绑定——每种语言都定义自己的languageOptions。具体支持哪些选项需要查阅对应插件的文档。例如eslint/json的jsonc语言就带有与 JSON 解析相关的选项。底层同样由languageSchemalib/config/flat-config-schema.js负责校验值必须是插件名/语言名格式的字符串。语言机制让 ESLint 从一个“JavaScript linter”扩展为多语言 lint 平台这一能力的详细设计可进一步阅读 docs/src/extend/languages.md。常见问题排查在配置插件过程中可能遇到两类典型问题插件规则使用 ESLint v9.0.0 的旧 API旧版插件基于 eslintrc 时代的 API 编写直接用于 flat config 会报错需要先让插件升级到兼容 v9 的 API。插件配置尚未升级到 flat config插件内置的configs仍是 eslintrc 格式。flat config 中需要通过extends引用插件的 flat config例如example/recommended对于旧式recommended配置可参考 docs/src/use/configure/migration-guide.md#use-eslintrc-configs-in-flat-config 了解如何在 flat config 中继续使用它们插件作者侧的双格式兼容写法flat/recommended与recommended并存见 docs/src/extend/plugins.md。小结在 flat config 体系中插件配置的核心脉络可以概括为四步引入import插件对象第三方包、本地文件或虚拟对象均可注册在plugins键中以“命名空间 → 插件对象”的形式注册命名空间决定规则、处理器、语言的前缀使用在rules中引用命名空间/规则名并指定严重度在processor中引用命名空间/处理器名处理非 JS 文件在language中引用命名空间/语言名扩展可 lint 的语言细化利用**/*.md/*.js这类嵌套 glob 对处理器产出的命名代码块做差异化配置。掌握这套机制后无论是引入成熟的生态插件如eslint-plugin-jsdoc、eslint/markdown、eslint/json还是为团队编写并使用本地/虚拟插件你都能在eslint.config.js中游刃有余地组织出一套清晰、可维护的 lint 体系。【免费下载链接】eslintFind and fix problems in your JavaScript code.项目地址: https://gitcode.com/GitHub_Trending/es/eslint创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考