使用esint的Angular项目非常慢



我有一个Angular12项目,由590个TypeScript文件组成。当我执行ng lint时,它会运行TSLint,并在大约5秒内完成。尽管如此,我还是按照Angular官方视频中的说明尝试升级到esint,现在ng lint需要10多分钟(实际上我没有让这个过程完成,我在10分钟时停止了它)。

我试图隔离这个问题,以了解原因是ng还是eslint,所以我使用npm i -g eslint全局安装了esint,并使用单个文件的定时信息运行它:

time TIMING=1 eslint /home/user/my-file.ts

即使是一个文件,也需要2分钟以上的时间。奇怪的是,eslint报告的每个规则只花了几毫秒,而Linux说它花了148秒(准确地说,它花了2分钟多):

Rule                                        | Time (ms) | Relative
:-------------------------------------------|----------:|--------:
@angular-eslint/no-conflicting-lifecycle    |     0.342 |    35.9%
@angular-eslint/no-input-rename             |     0.163 |    17.1%
@angular-eslint/template/banana-in-box      |     0.161 |    16.9%
@angular-eslint/no-output-rename            |     0.103 |    10.9%
@angular-eslint/component-class-suffix      |     0.100 |    10.5%
@angular-eslint/contextual-lifecycle        |     0.083 |     8.7%
@angular-eslint/directive-class-suffix      |     0.000 |     0.0%
@angular-eslint/no-empty-lifecycle-method   |     0.000 |     0.0%
@angular-eslint/no-host-metadata-property   |     0.000 |     0.0%
@angular-eslint/no-inputs-metadata-property |     0.000 |     0.0%
Rule | Time (ms) | Relative
:----|----------:|--------:
TIMING=1 eslint   148.14s user 4.47s system 190% cpu 1:19.96 total

我怎样才能让eslint跑得更快?

根本问题仍然是TypeScript编译器生成AST(抽象语法树)的开销,以及@TypeScript eslint/TypeScript将此AST转换为与eslint兼容的AST的工作。

然而,也有一些小的调整:

  • 设置.eslintignore以忽略不相关的目录,如node_modules和非TypeScript文件
  • 运行eslint:eslint --cache **/_.ts.存储有关已处理文件的信息时,请使用--cache标志,以便仅对更改后的文件进行操作,也可以使用"cache": true配置angular.json文件的lint部分

还有一整篇关于TypeScript性能的文章推荐:

  • 使用include属性设置tsconfig.json,以便在具有应编译的TypeScript文件的项目中仅指定输入文件夹
  • 避免添加太多的排除和包含文件夹,因为TypeScript文件必须通过遍历包含的目录来发现,所以运行多个文件夹实际上会减慢编译速度

查看Angular es lint指南中的性能说明

我建议仔细阅读Angular ts lint到es lint迁移指南中标题为"性能注意事项"的部分。

您可以通过运行以下命令开始调试您的问题:

DEBUG=typescript-eslint:* ng lint 

你会得到大量的输出,但其中可能有一些有价值的信息。

  • 检查(在前一行中)是否加载了预期的tsconfig文件。

  • 检查输出中是否有实际上不应该是linting过程的一部分的文件(即来自node_modules文件夹或dist文件夹等)。这可能会暴露出一些配置问题,您必须深入研究这些问题。

同时检查您是否获得如下大量输出:

typescript eslint:typescript estree:createProjectProgram正在为以下项创建项目程序:路径\到\您的\文件+0ms
typescript esling:typescript estree:createWatchProgram文件不属于任何现有程序,正在进行创建/更新路径\到\您的\文件+0ms
类型脚本eslint:类型脚本estree:createWatchProgram创建监视程序路径\到\your\文件+0ms

如果是这种情况,请仔细查看tsconfig中的文件和路径名。具体地说;baseUrl"包括";以及";排除";路径。


注意:例如;排除";spec文件的路径,但由于配置问题,它们实际上没有被正确排除在外,单独为这些文件创建项目程序大大降低了linting的速度


考虑仅将过梁限制为变化

如果在解决了上面提到的所有性能问题后,仍然不能提供您所希望的性能,您也可以考虑将linting限制为仅更改的文件。

这可以通过使用";高速缓存";angular.json文件中lint选项中的选项(通常是esint的--cache标志):

"lint": {
"builder": "@angular-eslint/builder:lint",
"options": {
"cache": true,
...
}
}

首先我会仔细检查parserOptionsref GitHub,如果它击中了整个回购。。。

如果是这样的话,

  • 您可以尝试通过将根目录中的tsconfig.json重命名为tsconfig.base.json,并在packages/some-package/.eslintrc.json内部将parserOptions.project指定为path.resolve(__dirname, './tsconfig.json')来解决此问题。

  • 在我的案例中,parserOptions.project被配置为./tsconfig.json,我猜在这种情况下,eslint试图在整个回购上运行tsc,而不是在影响性能的一个包上运行。


第二个,也可以考虑这里的这个不错的解释和一些建议。

根据他的建议:

"。。。根本问题仍然是TypeScript编译器生成AST的开销,而@TypeScript eslint/TypeScript estree将此AST转换为与eslint兼容的AST的工作">

他的帖子提供了一些不错的建议,包括缓存

  • 设置.eslintignore以忽略不相关的目录,如node_modules和非typescript文件运行eslint:eslint --cache **/_.ts时使用--cache标志。存储有关已处理文件的信息,以便仅对更改的文件进行操作。还有一整篇关于TypeScript性能的文章,其中建议:

由于某些原因,tsconfig.json中删除

"exclude": [
...
]

添加

"include": [
...
]

在运行npm run lint/ng lint时做出了巨大改进。

在我的案例中,time TIMING=1 npx eslint ./src/time ng lint运行的时间完全相同。

最新更新