Angular includes static code analysis as a default in the form of "linting" and it provides a "lowest common denominator" of rules that it will enforce during the linting process (ie running npm run lint). These rules generally came from the tslint and codelyzer projects and more recently these have been superseded by eslint and angular-eslint.
In this article we'll set our linting rules up to 11 to provide a very strict set of code quality. Adding this to your project will likely reveal hundreds or thousands of violations to rules which will be painfully tedious to clean up in your code however after this work is done keeping your code base clean will be easier and the benefits of less bugs and consistent coding styling will be enough to satisfy even Marie Kondo.
During this process remember this is like eating your greens, you may not like the taste but they are good for you, so resist the urge to turn off rules or disable them in code when they are hard to enforce.
We'll cover linting in both older Angular projects (using tslint and codelyzer) and newer ones (using eslint).
Tslint and Codelyzer
Older Angular projects will default to using tslint. Whilst it is a good idea to convert these to the newer eslint (migration guide here), we'll cover how to apply a strict set of rules with tslint and codelyzer.
Step 1: Installation
Ensure codelyzer and tslint are installed by running the following:
npm install codelyzer --save-dev --save-exact
npm install tslint-eslint-rules --save-dev --save-exact
Step 2: Update tslint.json
You'll need to turn up the dial to 11 on your linting rules by copying this tslint.json file and paste it into the tslint.json file of your project. There are over 80 rules turned on and they have been vetted to "make sense" with an Angular project and work well in IDEs like Visual Studio Code and IntelliJ.
Step 3: Blast Off
Now run your linter with:
npm run lint
At this point, after seeing all those errors, you may want to want to crawl back in bed and take the day off. Instead, lets be strategic about how to tackle the linting errors. First, we can automatically fix common linting problems by running:
npx tslint -p tsconfig.json --fix
Tip: Add this command to your package.json in scripts as a shortcut, or run it before commits.
Migrating to ESLint
If your Angular project is using tslint and/or codelyzer then you can migrate to eslint with these steps:
ng add @angular-eslint/schematics
Then migrate with:
ng g @angular-eslint/schematics:convert-tslint-to-eslint
(You may be asked to specify the project to convert, this can be found in angular.json and you will usually want "app")
Note: If you have a version of tslint installed less than 5.18 then you may also need to update it before this command will run successfully (eg npm install email@example.com)
This should migrate your linting rules from tslint.json to .eslintrc.json and you can delete the tslint.json file.
Linting with ESLint
If you have a recent Angular project then your linting will be done by ESLint. Rules are set in the .eslintrc.json file.
You'll need to turn up the dial to 11 on your linting rules by copying this .eslintrc.json file and paste it into the .eslintrc.json file of your project. There are over 30 rules turned on and they have been vetted to "make sense" with an Angular project and work well in IDEs like Visual Studio Code and IntelliJ.
Now run your linter with:
npm run lint
To fix linting errors automatically you can run:
ng lint --fix
Assuming the Angular CLI is installed globally this corrects fixable linting errors in your code.
I usually keep my Angular CLI only installed locally so I add a line in package.json under scripts of "fix": "ng lint --fix" so that i can run the command npm run fix
Fixing many of these linting errors may take a lot of time. A good strategy is to keep these work separate from the "real work" of implementing features and functionality changes (code reviews that mix linting fixes and functionality changes are difficult to review).
Choose your timing on when to apply linting fixes as it can be difficult to do code merges between branches when linting changes are part of those changes. A good time to clean up code is immediately after your last release and before any new work has started.
Finally, your end goal is to have no rule violations. If you can achieve this then you can also implement a check in your CI process to fail builds if there are linting errors (which help ensure that you do not forgot the linting step and your code quality suffers as a result).
Consistent code formatting can be considered a form of improving code quality as it levels the playing field for reading and understanding code. The tool prettier can be used to consistently format your code base. Try this to format all files in your Angular codebase:
npx prettier --write src/app/**/*
Like linting, you can also alter the rules applied for code formatting. A suggestion is to also run prettier on your codebase as part of a precommit hook (eg using Husky).