我有一个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,
...
}
}
首先我会仔细检查parserOptions
ref 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
运行的时间完全相同。