Angular eslint
Introduction
Last used 11 November 2021. Just a page to setup Eslint. This was done using
- Angular 13.0.1
- Nodejs 12.22.5
- npm 7.20.6
Update Angular
sudo npm uninstall -g @angular/cli
sudo npm uninstall -g @angular/core
sudo npm install -g @angular/core
sudo npm install -g @angular/cli
Install Dependencies
# Not working with Angular 13
# ng add @angular-eslint/schematics
npm install eslint-plugin-jsdoc --save-dev
npm install eslint-plugin-import --save-dev
npm install eslint-plugin-prefer-arrow --save-dev
npm i @angular-eslint/eslint-plugin-template --save-dev
npm i @angular-eslint/builder --save-dev
npm i @angular-eslint/eslint-plugin --save-dev
npm i @angular-eslint/template-parser --save-dev
npm i @typescript-eslint/eslint-plugin --save-dev
npm i @typescript-eslint/parser --save-dev
npm i eslint --save-dev
npm i eslint-config-prettier --save-dev
npm i eslint-plugin-prettier --save-dev
Install Dependencies
There is a bug in the @angular-eslint/schematics which means it tries to install the wrong version.
npm i @angular-devkit/build-angular --save-dev
npm i @angular-eslint/eslint-plugin-template --save-dev
npm i @angular-eslint/eslint-plugin --save-dev
npm i @angular-eslint/builder --save-dev
npm i @angular-eslint/template-parser --save-dev
npm i @typescript-eslint/parser --save-dev
npm i @typescript-eslint/eslint-plugin --save-dev
npm i eslint --save-dev
Add the wrong version of @angular-eslint/schematics. For me this was 1.2.0
ng add @angular-eslint/schematics
Now we can change the package.json to have the correct version.
...
"devDependencies": {
"@angular-devkit/build-angular": "~13.0.1",
"@angular-eslint/builder": "12.6.1",
"@angular-eslint/eslint-plugin": "12.6.1",
"@angular-eslint/eslint-plugin-template": "12.6.1",
"@angular-eslint/schematics": "12.6.1",
"@angular-eslint/template-parser": "12.6.1",
"@angular/cli": "~13.0.1",
"@angular/compiler-cli": "~13.0.0",
"@types/jasmine": "~3.10.0",
"@types/node": "^12.11.1",
Finally remove all package and install with dependencies
rm -rf node_modules
npm i --legacy-peer-deps
Add to angular.json the following at the bottom
"defaultProject": "bibble-park-app",
"cli": {
"defaultCollection": "@angular-eslint/schematics"
}
I then add the ng lint command for angular by adding the following to angular.json
"scripts": []
}
},
"lint": {
"builder": "@angular-eslint/builder:lint",
"options": {
"lintFilePatterns": [
"src/**/*.ts",
"src/**/*.html"
]
}
}
eslintrc.json
In the root of the project create a .eslintrc.json
{
"root": true,
"ignorePatterns": [
"projects/**/*"
],
"overrides": [
{
"files": [
"*.ts"
],
"parserOptions": {
"project": [
"tsconfig.json",
"e2e/tsconfig.json"
],
"createDefaultProgram": true
},
"extends": [
"plugin:@angular-eslint/ng-cli-compat",
"plugin:@angular-eslint/ng-cli-compat--formatting-add-on",
"plugin:@angular-eslint/template/process-inline-templates"
],
"rules": {
"@angular-eslint/component-selector": [
"error",
{
"type": "element",
"prefix": "app",
"style": "kebab-case"
}
],
"@angular-eslint/directive-selector": [
"error",
{
"type": "attribute",
"prefix": "app",
"style": "camelCase"
}
]
}
},
{
"files": [
"*.html"
],
"extends": [
"plugin:@angular-eslint/template/recommended"
],
"rules": {}
}
]
}
Update ng lint command
Edit the angular.json
"architect": {
"build": {
...
},
...
"lint": {
"builder": "@angular-eslint/builder:lint",
"options": {
"lintFilePatterns": ["src/**/*.ts", "src/**/*.html"]
}
},
...
}
Install Jasmine ESLint Plugins
If you want to install another plugin for ESLint, for example, to lint Jasmine spec files, install appropriate npm-package:
npm install eslint-plugin-jasmine --save-dev
We now need to add a section in the .eslintrc.json Each starts with { files: } and is under the overrides section.
overrides: [
...,
{
"files": [ "*.html" ],
"extends": [
"plugin:@angular-eslint/template/recommended"
],
"rules": {}
},
{
"files": ["src/**/*.spec.ts', 'src/**/*.d.ts"],
"parserOptions": {
"project": "./src/tsconfig.spec.json"
},
"extends": ["plugin:jasmine/recommended"],
"plugins": ["jasmine"],
"env": { "jasmine": true },
"rules": {
"@typescript-eslint/no-unused-vars": "off"
}
},
...
],
Install airbnb
Install the style guide
npm install eslint-config-airbnb-typescript --save-dev
As with the jasmine plugin add the *.ts entry under overrides. Add the following to .eslintrc.json
overrides: [
...
{
"files": ["*.ts"],
"parserOptions": {
"project": [
"tsconfig.*?.json",
"e2e/tsconfig.json"],
"createDefaultProgram": true
},
"extends": [
"airbnb-typescript/base",
"plugin:@typescript-eslint/recommended",
"plugin:@angular-eslint/ng-cli-compat",
"plugin:@angular-eslint/ng-cli-compat--formatting-add-on",
"plugin:@angular-eslint/template/process-inline-templates"
],
...
}
Now lets turn off
5:1 error Prefer default export import/prefer-default-export
Here is an example of how to turn off a rule
overrides: [
...
{
"files": ["*.ts"],
"parserOptions": {
"project": [
...
"extends": [
"airbnb-typescript/base",
"plugin:@typescript-eslint/recommended",
"plugin:@angular-eslint/ng-cli-compat",
"plugin:@angular-eslint/ng-cli-compat--formatting-add-on",
"plugin:@angular-eslint/template/process-inline-templates"
],
"rules": {
"import/prefer-default-export": "off",
...
Configuring Prettier
To add Prettier in ESLint config, we need to install Prettier itself, plugin with Prettier rules and config that turns off all rules that conflict with Prettier:
npm i prettier eslint-config-prettier eslint-plugin-prettier --save-dev
In .eslintrc.json config "overrides" in the bottom of "extends" property in the block of rules for files with .ts extension add Prettier settings:
"overrides": [
...
{
"files": ["*.ts"],
"parserOptions": {
"project": [
"tsconfig.*?.json",
"e2e/tsconfig.json"],
"createDefaultProgram": true
},
"extends": [
"airbnb-typescript/base",
"plugin:@typescript-eslint/recommended",
"plugin:@angular-eslint/ng-cli-compat",
"plugin:@angular-eslint/ng-cli-compat--formatting-add-on",
"plugin:@angular-eslint/template/process-inline-templates",
"plugin:prettier/recommended"
],
...
}
Configuration for Prettier should always be in the bottom of "extends" property, to turn off all the previous rules, which can conflict with Prettier.
prettier/@typescript-eslint turns off rules from @typescript-eslint, which can conflict with Prettier, and plugin:prettier/recommended does three things:
- enables eslint-plugin-prettier,
- marks prettier/prettier rules as "error",
- adds Prettier formatting rules eslint-config-prettier.
Prettier configuration
Prettier can format files with no configuration but for AirBnB code guide we need to specify some settings. Create .prettierrc.js in app root folder:
module.exports = {
trailingComma: "all",
tabWidth: 2,
semi: true,
singleQuote: true,
bracketSpacing: true,
printWidth: 100
};
This configuration will be used by ESLint and by Prettier if you want to run it separately. You can format your code with Prettier itself with prettier --write . or with Prettier Plugin for VS Code.
Configuring VS Code
VS Code can highlight errors which are found by ESLint and fix them on file save. To enable this feature install ESLint plugin for VS Code and create a file with configuration for workspace .vscode/settings.json:
"eslint.validate": [ "javascript", "typescript", "html"],
"eslint.options": {
"extensions": [".js", ".ts", "html"]
},
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true,
},
You can also install Prettier plugin for VS Code to format files with shift + option + f with Prettier.
Configuring Git Hooks
Git Hooks are scripts, which Git calls on certain events: commit, push, receive.
With Hooks we can run linting on commit creation to reduce errors falls into pull requests. For better work with Git Hooks install Husky, and to lint only staged files (it is necessary on big projects where linting can be very long) lint-staged:
npm i husky lint-staged --save-dev
Add new settings for this plugins in package.json:
"scripts": {
...,
},
"husky": {
"hooks": {
"pre-commit": "lint-staged --relative"
}
},
"lint-staged": {
"*.{js,ts}": [
"eslint --fix"
]
},
Lint-staged sends to the called command array of staged files. ng lint can't accept arrays of files and to use it we have to write an additional handler script. Or we can just run ESLint like in this example. You can use this solution for precommits, and ng lint for linting all files of project, for example, in CI pipeline.