typescript-eslint 的 parserOptions.project 使用宽 glob 导致变慢怎么优化?

typescript-eslint 的 parserOptions.project 使用宽 glob 导致变慢怎么优化? typescript-eslint 的 parserOptions.project 使用宽 glob 导致变慢怎么优化【免费下载链接】typescript-eslint:sparkles: Monorepo for all the tooling which enables ESLint to support TypeScript项目地址: https://gitcode.com/GitHub_Trending/ty/typescript-eslint在 typescript-eslint 中启用 type-aware 规则后ESLint 需要先让 TypeScript 分析整个项目lint 天然比传统规则慢。但如果parserOptions.project里写的是./**/tsconfig.json这类宽 glob解析器会递归检查所有目录来匹配 tsconfig产生远超预期的磁盘 IOlint 时间会明显慢于类型检查本身。本文基于项目官方的 Performance 与 Monorepo 排障文档给出两条修复路径把 glob 收窄为单层*或改用 v8 的parserOptions.projectService并说明如何验证效果。症状识别lint 明显慢于类型检查时才需要排查文档给出的基准是使用 type-aware linting 时lint 耗时应当与 build类型检查耗时大致相当。如果你的 lint 时间比同一项目的类型检查慢很多常见原因包括慢规则、慢类型以及过宽的文件范围parserOptions.project的宽 glob 就是其中的常见元凶之一。出现以下条件时本文适用正在使用需要类型信息的规则如recommendedTypeChecked、recommended-requiring-type-checking等共享配置通过parserOptions.project指定 tsconfig 路径且路径中使用了**宽 globlint 耗时显著高于类型检查耗时。宽 glob 为什么会慢两条机制都指向文件范围过宽使用parserOptions.project时对每个被 lint 的文件取第一个匹配的 project 路径作为它的 backing TSConfig。glob 里用**递归检查所有目录会让这个匹配过程产生比预期多得多的磁盘 IO。同理tsconfig 自身的include如果非常宽如**/*或者根本没有写include等价于提供了最宽的 glob就会有比预期多得多的文件被预解析TypeScript 甚至可能解析到 build 产物严重影响性能。文档要求include始终指向你真正想 lint 的目录。修复一收窄 glob用单层*代替**文档的建议是不要使用**递归检查所有目录的 glob改为一次只用一个*的路径prefer paths that use a single*at a time。以每个 package 一个tsconfig.json的 monorepo 为例。Flat Configeslint.config.mjs// ts-check import js from eslint/js; import { defineConfig } from eslint/config; import tseslint from typescript-eslint; export default defineConfig({ files: [**/*.{js,ts}], extends: [ js.configs.recommended, tseslint.configs.recommendedTypeChecked, { languageOptions: { parserOptions: { // Remove this line project: [./tsconfig.eslint.json, ./**/tsconfig.json], // Add this line project: [./tsconfig.eslint.json, ./packages/*/tsconfig.json], }, }, }, ], });Legacy Config.eslintrc.js/* eslint-env node */ module.exports { extends: [ eslint:recommended, plugin:typescript-eslint/recommended, plugin:typescript-eslint/recommended-type-checked, ], parser: typescript-eslint/parser, parserOptions: { // Remove this line project: [./tsconfig.eslint.json, ./**/tsconfig.json], // Add this line project: [./tsconfig.eslint.json, ./packages/*/tsconfig.json], tsconfigRootDir: __dirname, }, plugins: [typescript-eslint], root: true, };示例中packages是文档用的子目录名把它替换为你存放各 package 的实际目录名目录层级不同就多写一段单层*但不要回到**。两点配套说明project中的相对路径在tsconfigRootDir未设置时是相对当前工作目录解析的从非项目根目录运行 ESLint 时可能找不到 tsconfig。Legacy 示例中的tsconfigRootDir: __dirname就是为此设置建议保留。parserOptions.project方式下即使用了 project referencesTypeScript 也不会自动通过引用解析文件每个被引用的 tsconfig 都要单独加入project或由 glob 覆盖见 Parser 文档。修复二迁移到parserOptions.projectService文档推荐方向typescript-eslint v8 引入的projectService是目前文档推荐替代project的选项理由正是配置更简单、lint 更快。它会自动为每个文件使用最近的tsconfig.json并且对宽 tsconfig includev8 的 project service不需要任何额外配置宽 glob 问题直接解决对 monorepo 同样不需要额外配置Monorepo 文档明确写着如果你在使用parserOptions.projectService不需要这份指南。配置示例Parser 文档export default [ { languageOptions: { parserOptions: { projectService: true, }, }, }, ];module.exports { parser: typescript-eslint/parser, parserOptions: { projectService: true, }, };注意同时启用project和projectService会报错迁移时要把原来的project配置删掉Enabling project does nothing when projectService is enabled. You can remove the project setting验证效果先建立基线文档建议单独运行tsc得到整个项目类型检查速度的 baseline。重新运行你的 lint 命令并对比type-aware linting 的耗时应当与 build/类型检查耗时大致相当。如果收窄 glob或切换到projectService后lint 从明显慢于类型检查回到大致相当说明宽 glob 问题已解决。需要更细的排查时文档给出三种开详细日志的方式任选其一TIMING1ESLint 自带选项给出各规则速度的总览。例如TIMING1 eslint 你的lint命令。注意由于 TypeScript 有内部缓存项目的第一条 type-aware 规则几乎总是看起来最慢比较规则速度时要一次只启用一条规则单独测量DEBUGtypescript-eslint:* eslint 你的lint命令开启debug包的详细日志parserOptions.debugLeveltrue等价于[typescript-eslint]也支持eslint、typescript组合或直接用eslint --debug开启 CLI 全部调试日志。已知限制大型 monorepo超过 10 个 package使用多个 tsconfig 的project数组方式时有报告在足够大且相互依赖的项目上触发 OOM文档说明触发此 OOM 的情况很少建议先搭建测试。若确实遇到文档给出的临时替代方案有两个合并为单个根级tsconfig.eslint.json或用 shell 脚本一次只 lint 一个 package见 Monorepo 配置文档。若仍出现FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory这类内存错误可以用NODE_OPTIONS--max-old-space-size8192 eslint 你的lint命令提高 Node.js 内存上限。副作用是允许 ESLint 消耗更多内存且它不减少工作量文档强调这是最后手段应优先降低类型复杂度。tsconfig 里宽include**/*或缺省include是与宽 glob 同一性质的文件范围问题。如果改了project后仍然慢检查每个 tsconfig 的include是否精确指向你要 lint 的目录而不是**/*。相关文档PerformanceMonorepo ConfigurationParser 文档Linting with Type Information【免费下载链接】typescript-eslint:sparkles: Monorepo for all the tooling which enables ESLint to support TypeScript项目地址: https://gitcode.com/GitHub_Trending/ty/typescript-eslint创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考