Reputation: 23035
I have an Angular12 project composed of 590 TypeScript files. When I do ng lint
it runs TSLint and finishes in about 5 seconds. Nonetheless, I tried upgrading to eslint following the instructions on this official video from Angular, and now ng lint
takes more than 10 minutes (I actually didn't let the process finish, I stopped it at the 10 minutes mark).
I tried to isolate the issue to know if the cause was ng
or eslint
so I installed eslint globally with npm i -g eslint
and run it with timing information for a single file:
time TIMING=1 eslint /home/user/my-file.ts
And even for this single file it took more than 2 minutes. It is odd that eslint
is reporting each rule took just some milliseconds, whereas Linux says it took 148 seconds (which is accurate, it took more than 2 minutes):
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
How can I make eslint go faster?
Upvotes: 25
Views: 10531
Reputation: 495
The underlying issue is still the overhead of the TypeScript compiler generating an AST (Abstract Syntax Tree), and the @typescript-eslint/typescript-estree work of converting this AST to an ESLint compatible AST.
However, there are some minor tweaks:
.eslintignore
to ignore irrelevant directories like node_modules
and non-TypeScript files--cache
flag when running eslint: eslint --cache \*\*/\_.ts.
Store the info about processed files in order to only operate on the changed ones, or you may config the angular.json
file's lint
section with "cache": true
.There is also a whole article on TypeScript performance which recommends:
tsconfig.json
with the include property to specify only input folders in a project with TypeScript files that should be compiled.Upvotes: 7
Reputation: 372
For some reasons, removing from tsconfig.json
"exclude": [
...
]
or adding
"include": [
...
]
Makes huge improvements when running npm run lint
/ ng lint
.
In my case time TIMING=1 npx eslint ./src/
or time ng lint
was running for exactly the same time.
Upvotes: -1
Reputation: 44393
I suggest carefully reading through this section titled Notes on Performance of the Angular ts-lint to es-lint migration guide.
You can start debugging your problem by running the following command:
DEBUG=typescript-eslint:* ng lint
You will get an enormous amount of output, but there could be some valuable information in there.
Check (in one of the first lines) whether the expected tsconfig
files are loaded.
Check the output for files that are actually not supposed to be part of the linting process (i.e. from node_modules
folder or dist
folder, etc). This might expose some configuration issues for which you have to dig deeper.
Also check whether you get a lot of output as follows:
typescript-eslint:typescript-estree:createProjectProgram Creating project program for: path\to\your\file +0ms
typescript-eslint:typescript-estree:createWatchProgram File did not belong to any existing programs, moving to create/update. path\to\your\file +0ms
typescript-eslint:typescript-estree:createWatchProgram Creating watch program for path\to\your\file +0ms
If that is the case have a good look at the files and path names inside your tsconfig
. Specifically "baseUrl", "include" and "exclude" paths.
Note: I had for example "exclude" paths for spec files, but because of a configuration issue they were actually not excluded correctly and creating project programs for these files individually was slowing down the linting dramatically.
If after resolving all performance issues mentioned above does still not give you the performance you were hoping for you could also consider limiting the linting to changed files only.
This can be done by using the "cache" option in the lint options in your angular.json
file (normally the --cache flag for eslint):
"lint": {
"builder": "@angular-eslint/builder:lint",
"options": {
"cache": true,
...
}
}
Upvotes: 8
Reputation: 7439
First I would double check parserOptions
ref GitHub, if its hitting the entire repo...
If thats the case,
you can try and solve it by renaming tsconfig.json
in the root to tsconfig.base.json
and inside packages/some-package/.eslintrc.json
specified parserOptions.project
as path.resolve(__dirname, './tsconfig.json')
.
In my case the parserOptions.project
was configured to ./tsconfig.json
and I guess in this case eslint
tried to run tsc on the entire repo instead of one package which affected the performance.
Second, also consider this nice explanation here with some suggestions.
Per his recommendations:
"...The underlying issue is still the overhead of the TypeScript compiler generating an AST, and the @typescript-eslint/typescript-estree work of converting this AST to an ESLint compatible AST."
His post offered some nice suggestions including caching
.eslintignore
to ignore irrelevant directories like node_modules and non-typescript files
Use the --cache
flag when running eslint: eslint --cache \*\*/\_.ts
. Store the info about processed files in order to only operate on the changed ones.
There is also a whole article on TypeScript performance which recommends:Upvotes: 2