Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular project with eslint is super slow

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?

like image 249
Daniel Avatar asked Aug 02 '21 22:08

Daniel


People also ask

Why does ESLint take so long?

The cause of the slow ESLint runtime with eslint-plugin-prettier is because that plugin also runs Prettier under the hood to detect and raise issues when the code differs from Prettier's expected output.

Does ESLint work with Angular?

Rules specific for Angular 1 or 2We can use a property, defined in the ESLint configuration file, in order to know which version is used : Angular 1 or Angular 2. based on this property, you can create rules for each version.

Does Angular use TSLint or ESLint?

Since the Angular CLI was released it has included linting using the ng lint command. With the release of Angular v11 it was announced that tslint which ng lint used behind the scenes for the linting was being replaced with eslint.

Does ESLint use Codelyzer?

TSLint also has a dependency on Codelyzer, where ESLint does not.


Video Answer


2 Answers

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.

However, there are some minor tweaks:

  • Set up .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:

  • Set up tsconfig.json with the include property to specify only input folders in a project with TypeScript files that should be compiled.
  • Avoid adding too many exclude and include folders, since TypeScript files must be discovered by walking through included directories, so running through many folders can actually slow down compilation.
like image 137
Rudy A. Hernandez Avatar answered Oct 22 '22 01:10

Rudy A. Hernandez


Check the Notes on Performance in the Angular es-lint guide

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.


Consider limiting linting to changes only

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,
    ...
  }
}
like image 3
Wilt Avatar answered Oct 22 '22 03:10

Wilt