
ESLint 核心术语全解析从 AST 到 Violation 的完整技术指南【免费下载链接】eslintFind and fix problems in your JavaScript code.项目地址: https://gitcode.com/GitHub_Trending/es/eslint本篇技术指南以 ESLint 官方术语表为核心骨架系统梳理 ESLint 生态中最常被提及的 30 余个核心概念——包括抽象语法树AST、配置体系Flat Config、Config Object、Override、规则机制Rule、Severity、Fix、Suggestion、分析流程Parser、ESQuery、Report等。读完本文你将掌握 ESLint 的完整技术词汇表能够准确理解官方文档、插件源码与社区讨论中的术语含义并能在实际配置中正确运用这些概念。文中所有关键术语均结合当前仓库的源码实现与官方文档进行印证帮助你建立从术语到实现的完整认知链路。一、语法表示层AST、Node 与 ESTreeAbstract Syntax Tree (AST)抽象语法树AST是代码语法的一种结构化表示。源代码中的每一个片段在 AST 中对应一个 节点Node每个节点可以拥有任意数量的属性其中部分属性用于存储子节点从而形成一棵树状结构。ESLint 采用的 AST 格式是 ESTree 标准。规则Rule 会接收一棵 AST并在发现 违规Violation 时在 AST 的对应位置上报违规信息。换句话说AST 是 ESLint 理解源代码的中间语言——无论是内置规则还是插件规则全部围绕 AST 展开工作。Node节点Node是 AST 中的一段代码。每个节点代表源代码中的一种语法类型。例如在1 2;的 AST 中1 2就是一个BinaryExpression二元表达式节点。ESLint 使用 ESQuery 库来解析 选择器Selector让规则能够在 AST 中精确搜索目标节点。ESTreeESTree是 ESLint 用来将 JavaScript 语法表示为 AST 的格式标准。例如代码1 2;的 ESTree 表示大致如下{ type: ExpressionStatement, expression: { type: BinaryExpression, left: { type: Literal, value: 1, raw: 1 }, operator: , right: { type: Literal, value: 2, raw: 2 } } }静态分析Static Analysis 工具如 ESLint的典型工作方式就是把语法转换为 ESTree 格式的 AST 后再进行处理。源码印证AST 与遍历逻辑在仓库中位于 lib/linter/source-code-visitor.js 与 lib/linter/source-code-traverser.js。规则通过访问者visitor模式在遍历 AST 时被逐个触发这一点在后文 Rule 一节中还会展开。二、配置体系Config File、Config Array 与 Config ObjectConfig FileConfiguration File配置文件Config File是保存 ESLint 解析文件方式与运行规则偏好的文件。ESLint 配置文件命名为eslint.config.(c|m)?(j|t)s形式即eslint.config.jseslint.config.mjseslint.config.cjseslint.config.ts/eslint.config.mts/eslint.config.ctsTypeScript 配置需额外设置每个配置文件导出的是一个 配置数组Config Array数组中包含一个或多个 配置对象Config Object。例如下面的eslint.config.js以error级别启用prefer-const规则import { defineConfig } from eslint/config; export default defineConfig([ { rules: { prefer-const: error, }, }, ]);若项目在package.json中声明了type: commonjs则eslint.config.js需使用 CommonJS 格式const { defineConfig } require(eslint/config); module.exports defineConfig([ { rules: { semi: error, prefer-const: error, }, }, ]);更完整的配置说明参见 Configuration Files。Config Array配置数组Config Array是配置文件内的配置对象数组。数组中的对象按顺序求值后面的对象可以覆盖前面对象已设置的配置。这一后写优先last-wins语义是理解 ESLint 配置合并规则的基础——配置对象中没有显式声明的键不受影响只有重复声明的键才会被覆盖。Config Object配置对象Config Object是配置文件的条目包含 ESLint 在一组文件上执行所需的全部信息。每个配置对象可能包含以下属性部分属性作用name配置对象的名称用于错误信息与 config inspector 中标识filesglob 模式数组指定该配置对象应用于哪些文件ignoresglob 模式数组指定该配置对象不应用于哪些文件language用于 lint 的语言格式为pluginName/languageName默认js/jslanguageOptions语言相关的解析设置ecmaVersion、sourceType、globals、parser、parserOptionslinterOptionslint 过程相关设置noInlineConfig、reportUnusedDisableDirectives、reportUnusedInlineConfigsprocessor预处理器对象或插件内处理器名称plugins插件名称到插件对象的映射rules已配置的规则集合settings供所有规则共享的名称-值信息配置对象能够描述在哪些文件上运行、如何处理不同文件类型、引入哪些插件、以及如何运行规则。默认情况下 ESLint 会 lint 匹配**/*.js、**/*.cjs和**/*.mjs的文件。详细说明参见 Configuration Files Configuration Objects。三、规则执行机制Rule、Severity、Violation、ReportRule规则Rule是检查 AST 是否符合预期模式的代码。当规则的预期未被满足时它会创建一条 违规Violation。ESLint 内置了大量针对常见 JavaScript 问题的规则更多规则可通过 插件Plugin 加载。规则是 ESLint 的核心构建单元——规则校验你的代码是否满足某项预期以及不满足时该做什么内置规则总览参见 Core Concepts Rules。从源码结构看仓库中的每条内置规则都是一个独立模块位于 lib/rules/ 目录下如 lib/rules/no-undef.js、lib/rules/semi.js 等并在 lib/rules/index.js 中统一注册导出。Severity严重级别Severity决定规则以何种级别运行如果运行的话。ESLint 支持三个严重级别off0不运行该规则。warn1运行规则但除非配合--max-warnings标志否则不会因其违规而让进程以非零状态码退出。error2运行规则一旦产生任何违规进程即以非零状态码退出。源码印证severity 的字符串/数字归一化逻辑位于 lib/shared/severity.js。其中的normalizeSeverityToString与normalizeSeverityToNumber两个函数都接受off/0、warn/1、error/2的任意一种写法并将其统一为内部标准值传入其他值则抛出Invalid severity value错误。这说明字符串与数字两种写法等价并非文档口头约定而是有强制性的实现保证。规则配置的完整说明参见 Configure Rules。Violation违规Violation是规则对代码中不符合其预期的区域给出的指示。每条违规都指明源代码中的一段范围range和一条错误消息message还可能附带一个 修复Fix 和/或 建议Suggestion用于说明如何改进违规代码。源码印证规则通过context.report()上报违规例如 lib/rules/no-undef.js 中针对未定义标识符调用context.report({ node: identifier, messageId: undef, data: identifier })其消息模板{{name}} is not defined.定义在该规则的meta.messages中。违规信息的聚合与文件级报告处理位于 lib/linter/file-report.js。Report报告Report是单次 ESLint 运行产生的全部违规的集合。当 ESLint 处理源文件时它会为每个源文件生成 AST并将该 AST 传递给每个已配置的规则各规则产生的违规会被打包收集最终交给 格式化器Formatter 呈现给用户。这条流水线——源码 → 解析 → 规则遍历 → 违规收集 → 格式化输出——正是 ESLint 的核心工作流。Override覆盖Override指某个 配置对象Config Object 或 内联配置Inline Config 设置了新的严重级别和/或规则选项从而取代此前设置的严重级别和/或选项。以下配置文件在*.test.js文件中把no-unused-expressions从error覆盖为offimport { defineConfig } from eslint/config; export default defineConfig([ { rules: { no-unused-expressions: error, }, }, { files: [*.test.js], rules: { no-unused-expressions: off, }, }, ]);而下面的内联配置则将no-unused-expressions设为error/* eslint no-unused-expressions: error */覆盖机制与配置数组后写优先的求值顺序一脉相承靠后的配置对象或文件内的内联注释可以精确地针对特定文件/代码段调整规则行为。扁平配置的合并实现可参考 lib/config/flat-config-array.js。Inline ConfigConfiguration Comment内联配置配置注释是一种源代码注释用来把规则配置为不同的严重级别和/或选项组合。内联配置使用与配置文件类似的语法可以按名称指定任意数量的规则、它们的新严重级别以及可选的新选项。例如下面的内联配置注释同时关闭了eqeqeq规则并把curly规则设为error/* eslint eqeqeq: off, curly: error */你也可以使用数字等价写法/* eslint eqeqeq: 0, curly: 2 */如果规则带额外选项可使用数组字面量语法数组第一项始终是严重级别/* eslint quotes: [error, double], curly: 2 */内联配置注释还可以附带描述用两个或更多连续-与配置分隔/* eslint eqeqeq: off, curly: error -- Heres a description about why this configuration is necessary. */ESLint 还支持通过linterOptions.reportUnusedInlineConfigs默认off报告未生效的内联配置注释。完整用法参见 Rules Use configuration comments。四、修复能力Fix、Suggestion 与格式化规则Fix修复Fix是规则违规的一种可选附加信息描述如何自动纠正该违规。修复一般安全到可以自动应用——它们不应改变代码行为。当使用--fix标志运行时ESLint 会尝试在报告中应用尽可能多的修复但不保证所有修复都会被应用例如修复之间存在冲突时。常见的编辑器扩展也会自动应用修复。规则违规除了修复之外还可能包含不安全、不会自动应用的文件改动即 建议Suggestion。源码印证修复器fixerAPI 位于 lib/linter/rule-fixer.js它提供insertTextAfter、remove、replaceText等方法来描述代码改动多条修复的实际落盘由 lib/linter/source-code-fixer.js 完成该模块负责冲突消解与排序。--fix标志的说明见 Command Line Interface。Suggestion建议Suggestion是规则违规的另一种可选附加信息描述用户如何手动调整代码以解决违规。建议通常不安全不能自动应用因为它们会改变代码行为。ESLint 本身不会直接应用建议但会把建议提供给可能选择应用它们的集成方例如编辑器扩展。规则违规中可能同时包含可安全自动应用的 修复Fix 与需要人工判断的建议。修复与建议的区别可归结为两点修复不改业务逻辑、可由 CLI--fix或编辑器自动应用建议可能改变业务逻辑、只能通过编辑器集成手动应用。文档约定中可能提供修复的规则用 标记可能提供建议的规则用 标记见 Rules 列表页。Formatting (Rule) 与 Stylistic (Rule)格式化规则Formatting Rule是只关注格式化问题如分号、空白的规则不改变应用逻辑属于 风格规则Stylistic Rule 的子集。ESLint已不再推荐使用格式化规则并已弃用其内置的格式化规则转而推荐使用专门的格式化工具如 Prettier、dprint或使用社区提供的格式化相关 lint 规则。风格规则Stylistic Rule强制的是某种偏好而非逻辑问题涵盖格式化规则、命名约定以及等价语法之间的一致性选择。ESLint 的内置风格规则已功能冻结除支持新的 ECMAScript 版本外不会再获得新功能。这是 2020 年规则政策调整与 2023 年格式化规则弃用决定的延续相关背景可参见仓库中的 rule-deprecation.md。FormatterLinting与 FormatterTool格式化器FormatterLinting 场景是呈现 ESLint 生成 报告Report 的包。ESLint 内置了多个报告器包括stylish默认、json、html等。更多信息参见 Formatters。格式化器Formatter工具场景则是指一种快速重排代码、但不改变其逻辑或名称的 静态分析 工具。格式化器通常只修改代码的琐碎部分trivia——分号、间距、换行、空白等而这些改动一般不会改变代码的 AST。生态中常见的格式化工具包括 Prettier、dprint 等。需要强调的是ESLint 是 linter 而非 formatter但 ESLint 规则确实可以对源代码应用格式化改动即前述格式化规则。五、查询与解析Parser、ESQuery、SelectorParser解析器Parser是包含一个方法的对象该方法读取字符串并将其转换为标准化格式。ESLint 使用解析器将源代码字符串转换为 AST 形状。默认情况下ESLint 使用内置的Espree解析器它生成的 AST 与标准 JavaScript 运行时和版本兼容。自定义解析器让 ESLint 能够解析非标准 JavaScript 语法通常随共享配置或插件一并提供因此使用者一般无需直接接触它们。例如typescript-eslint/parser就让 ESLint 能够解析 TypeScript 代码。使用解析器的详细说明参见 Configure a Parser。仓库中解析器服务的实现位于 lib/services/parser-service.js。ESQueryESQuery是 ESLint 用来解析 选择器Selector 语法以查询 AST 中 节点Node 的库。ESQuery 将CSS 选择器语法解释到 AST 节点属性上。典型的 ESQuery 选择器包括BinaryExpression选择所有类型为BinaryExpression的节点BinaryExpression[operator]选择所有operator为的BinaryExpression节点BinaryExpression Literal[value1]选择所有value为1、且直接父节点是BinaryExpression的Literal节点源码印证ESLint 对 ESQuery 的封装位于 lib/linter/esquery.js。该模块不仅转发了esquery库的parse/matches能力还做了两层增强一是选择器缓存——用selectorCache一个Map缓存已解析的选择器避免重复解析开销parse函数在 lib/linter/esquery.js#L288-L310二是复杂度分析——analyzeParsedSelector统计每个选择器的属性查询数与标识符数据此计算特异性specificity用于排序ESQueryParsedSelector.compare。这意味着 ESLint 能够为规则自动推导出哪些节点类型可能触发该选择器从而在遍历 AST 时只投递可能匹配的节点提升 lint 性能。Selector选择器Selector是描述如何在 AST 内搜索 节点Node 的语法。ESLint 规则Rule 使用 ESQuery 选择器来定位需要检查的节点。选择器语法是编写自定义规则时最常用的工具之一它让开发者可以用类似 CSS 的方式类型选择器、属性选择器、子代组合器、伪类等精准描述要检查哪类代码。六、全局与上下文Global Declaration、Global VariableGlobal Declaration全局声明Global Declaration是向 ESLint 描述某个应在运行时存在的 JavaScript 全局变量Global Variable 的方式。全局声明通知那些检查全局变量正确使用的 lint 规则。例如no-undef规则会对引用了未在配置的全局变量列表中定义的全局变量产生违规。在 配置文件 中全局变量被定义为 JavaScript 对象languageOptions.globals。配置全局变量的方法参见 Configure Language Options Specify Globals。源码印证lib/rules/no-undef.js 的实现展示了全局声明的实际消费方式规则在Program:exit时获取全局作用域遍历globalScope.through中的每个引用即作用域中穿透出来的未解析标识符对每个引用上报违规。其可选选项typeof默认false用于控制是否对typeof操作符中的变量引用告警——规则中通过hasTypeOfOperator判断父节点是否为typeof一元表达式。Global Variable全局变量Global Variable是存在于全局作用域中的运行时变量所有模块和脚本都可访问。JavaScript 中的全局变量声明在globalThis对象上在 Node.js 中通常别名为global在浏览器中为window。你可以通过 全局声明Global Declaration 让 ESLint 知道你代码中使用了哪些全局变量。这在代码依赖外部环境注入如 HTML 脚本引入的全局变量时尤为重要。七、扩展体系Plugin、Processor、Shareable ConfigPlugin插件Plugin是一个可以包含一组 配置共享配置、处理器Processor 和/或 规则Rule 的包。插件的一个典型用途是为某个框架强制执行最佳实践——例如 Angular 生态的官方插件就包含使用 Angular 框架的最佳实践规则。配置插件的详细说明参见 Configure Plugins。仓库自身的插件开发指南参见 Plugins。Processor处理器Processor是插件的一部分负责从其他类型的文件中提取 JavaScript 代码然后让 ESLint 对这些提取出的代码执行 lint。例如eslint/markdown就包含一个处理器能把 Markdown 文件中的代码块文本转换为可被 lint 的代码。配置处理器的说明参见 Plugins Specify a Processor。处理器服务的底层实现位于 lib/services/processor-service.js它通过preprocess与postprocess两个阶段完成提取-合并循环。Shareable ConfigConfiguration共享配置Shareable Config是提供预定义 配置文件 配置的模块。共享配置可以配置与配置文件完全相同的信息包括 插件Plugin 和 规则Rule。共享配置常与插件一同提供——许多插件会提供名为recommended推荐的配置启用它们建议的起始规则集。例如eslint-plugin-solid提供了一个可共享的 recommended 配置import { defineConfig } from eslint/config; import js from eslint/js; import solid from eslint-plugin-solid/configs/recommended; export default defineConfig([js.configs.recommended, solid]);共享配置的编写与发布指南参见 Share Configurations。八、配置格式演变Flat Config 与 Legacy ConfigFlat Config扁平配置Flat Config是 ESLint 当前的配置文件格式。扁平配置文件命名为eslint.config.(c|m)?(j|t)s形式。之所以称为扁平是因为所有嵌套都必须在同一个配置文件中完成与此相对Legacy 配置格式 允许配置在项目的子目录间嵌套分布。扁平配置的设计动机在于消除.eslintrc体系中层叠配置带来的查找歧义与继承复杂性让配置结果完全由当前目录的单个配置文件决定。Legacy ConfigLegacy 配置Legacy Config是 ESLint 之前的配置文件格式现已被 Flat Config 取代。Legacy 配置命名为.eslintrc.*形式并允许在项目的子目录中跨文件嵌套。从仓库结构可以观察到这一演进的痕迹docs/src/use/下既有 migrate-to-9.0.0.md 等迁移指南lib/config/下同时保留着 config.js、config-loader.js旧体系与 flat-config-array.js、flat-config-schema.js新体系等实现文件。九、定位与边界Linter、Static Analysis、Type CheckerLinterLinter代码检查器是一种 静态分析 工具可以对一组 规则Rule 在源代码上的运行结果进行 报告Report每条规则都可能在源代码中报告任意数量的 违规Violation。ESLint 是 JavaScript 及其他 Web 技术中最常用的 linter 之一。需要注意的是linter 与 格式化工具Formatter 和 类型检查器Type Checker 是相互独立的工具类别。Static Analysis静态分析Static Analysis是在不构建、不运行源代码的情况下分析源代码的过程。linter如 ESLint、格式化工具和类型检查器都属于静态分析工具。静态分析与动态分析相对——动态分析是在代码构建并执行之后评估代码的过程单元测试、集成测试、端到端测试都是动态分析的常见例子。Type Checker类型检查器Type Checker是一种构建项目代码结构与数据形状完整理解的 静态分析 工具。类型检查器通常比 linter更慢但更全面linter 传统上一次只针对单个文件或代码片段的 AST 操作而类型检查器理解跨文件依赖与类型。TypeScript 是 JavaScript 最常用的类型检查器typescript-eslint 项目提供了在 lint 规则中使用类型检查器的集成能力。Logical Rule逻辑规则Logical Rule是检查代码如何运行以发现问题的一类 规则Rule。许多逻辑规则致力于发现潜在崩溃如no-undef、非预期行为如no-sparse-arrays和未使用代码如no-unused-vars。ESLint 内置的全部逻辑规则可以在 Rules Possible Problems 下查看完整列表。十、术语速查表为便于快速检索将本文全部术语按主题归类如下主题域术语语法表示Abstract Syntax Tree (AST)、Node、ESTree配置体系Config File、Config Array、Config Object、Flat Config、Legacy Config、Override规则机制Rule、Severity、Violation、Report、Logical Rule、Stylistic Rule、Formatting (Rule)修复能力Fix、Suggestion查询解析Parser、ESQuery、Selector全局上下文Global Declaration、Global Variable扩展体系Plugin、Processor、Shareable Config配置注释Inline Config (Configuration Comment)输出呈现Formatter (Linting)、Formatter (Tool)分析类别Linter、Static Analysis、Type Checker十一、从术语到实践如何继续深入术语是理解 ESLint 的入口但真正的掌握来自实践。建议按照以下路径继续深入动手配置参照 Configuration Files 创建你自己的eslint.config.js体验 Config Object 的files/ignores/rules组合与 Override 语义。观察规则行为阅读 Rules 下任一规则的文档如 no-undef、eqeqeq对照 lib/rules/ 中对应源码理解文档术语如何映射为实现逻辑。阅读测试用例仓库的 tests/lib/rules/ 目录包含全部内置规则的测试展示了每条规则在各类输入下的违规/修复/建议行为是理解 Fix 与 Suggestion 区别的最佳教材。编写自定义规则结合 Custom Rules 指南使用 ESQuery Selector 编写你自己的规则实践 AST、Node、Violation 等全部核心概念。通过本文的术语地图与源码印证你现在已经拥有阅读 ESLint 官方文档、理解插件源码、排查配置问题的完整知识框架。【免费下载链接】eslintFind and fix problems in your JavaScript code.项目地址: https://gitcode.com/GitHub_Trending/es/eslint创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考