Angular eslint

From bibbleWiki
Jump to navigation Jump to search

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 and move it to the dev devDepenedencies.

...
  "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",

Remove all package and install with legacy peer dependencies

rm -rf node_modules
npm i --legacy-peer-deps

We can now modify the angular.json the following at the bottom

"defaultProject": "bibble-park-app",
"cli": {
    "defaultCollection": "@angular-eslint/schematics"
}

And 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.