Nous portons le projet Angular sur ESLint, avec Prettier, Husky et lint-staged

Bonjour, Habr! Mon nom est Bogdan, je travaille en tant que chef d'équipe PIC Digital Front-End. Nous développons la plupart des projets sur Angular, et récemment j'ai décidé de revoir nos guides de style, ainsi que d'ajouter de nouveaux outils pour un travail plus pratique.

En tant que linter, j'ai décidé d'utiliser ESLint, car ils prévoient d'y transférer bientôt Angular. Et dans cet article, je veux partager des instructions sur le passage de TSLint à ESLint, et en même temps dire comment exécuter Prettier à partir d'ESLint, comment ajouter des règles de guide de style AirBnB et comment rendre le linting pratique et invisible en définissant VS Code et Git hooks.

Prettier & ESLint


ESLint est un outil d'analyse de code statique, les règles sont divisées en deux groupes:

  • Formatage - pour regrouper le code en une seule vue: longueurs de ligne, virgules, points-virgules, etc.
  • Qualité du code - recherche de modèles de code problématiques: code inutile, erreurs.

Prettier est un outil de formatage de code automatique.

La question qui m'intéressait était: pourquoi utiliser Prettier si ESLint peut également formater du code?

La réponse est simple - Prettier formate bien mieux le code: supprime tout formatage et réécrit complètement le code dans un seul style. Cela permet aux développeurs d'oublier la mise en forme du code et de ne pas perdre de temps à discuter du style de code pour révision. Par exemple, nous avons une longue ligne de code:

image

si nous essayons de changer la mise en forme via ESLint, cela nous donnera simplement une erreur:

eslint example.ts --fix

output:
error    This line has a length of 97. Maximum allowed is 80

Un tel exemple montre que linter ne peut pas toujours aider à la mise en forme du code et que les développeurs peuvent formater ce code de différentes manières, en fonction de leurs considérations personnelles.

Si nous enregistrons ou formater le fichier avec Prettier, la ligne prendra la forme:

image

Prettier fournit un style uniforme dans toute la base de code. Par conséquent, il peut et doit être utilisé avec ESLint, mais vous devez les configurer afin qu'ils n'interfèrent pas entre eux.

Configuration d'ESLint


L'essence du linting ESLint réside dans les analyseurs qui transforment le code en AST (arbre de syntaxe abstraite) pour un traitement logiciel ultérieur, et des plugins qui contiennent des règles, par exemple, des règles recommandées pour le linting TypeScript ou des règles de guide de code AirBnB.

Installation


Pour migrer une application Angular vers ESLint, nous avons besoin des dépendances suivantes:


Pour les installer, il suffit d'exécuter la commande:

ng add @angular-eslint/schematics

Au moment de l'écriture, typescript-eslint et angular-eslint n'ont pas tous les équivalents pour les règles dans la configuration standard de Codelyzer pour TSLint, mais la plupart d'entre elles existent déjà. Vous pouvez surveiller l'état actuel du transfert des règles de TSLint vers ESLint dans les mono-référentiels Angular ESLint et TypeScript ESLint .

Configuration de configuration


Tout ce dont nous avons besoin pour peloter les applications angulaires, nous les avons installées. Passons maintenant à la configuration d'ESLint. Créons un fichier .eslintrc.js et ajoutons les paramètres recommandés pour Angular ESLint:

module.exports = {
  extends: ['plugin:@angular-eslint/recommended'],
  rules: {
    '@angular-eslint/directive-selector': [
      'error',
      { type: 'attribute', prefix: 'app', style: 'camelCase' },
    ],
    '@angular-eslint/component-selector': [
      'error',
      { type: 'element', prefix: 'app', style: 'kebab-case' },
    ],
  },
  overrides: [
    //   ,       *.component.ts
    {
      files: ['*.component.ts'],
      parser: '@typescript-eslint/parser',
      parserOptions: {
        ecmaVersion: 2020,
        sourceType: 'module',
      },
      plugins: ['@angular-eslint/template'],
      processor: '@angular-eslint/template/extract-inline-html',
    },
  ],
};

Les configurations peuvent être décrites dans différents formats: fichier JavaScript, JSON ou YAML. Vous pouvez laisser des commentaires en JavaScript.

«Plugin: @ angular-eslint / recommended» contient les paramètres de 3 plugins à la fois: «@ typescript-eslint / eslint-plugin», «@ angular-eslint / eslint-plugin» et «@ angular-eslint / eslint-plugin-template " Vous pouvez lire les règles qu'il établit ici .

Mise à jour de la commande Ng Lint


Toujours dans la configuration angular.json, vous devez mettre à jour la commande ng lint pour exécuter @ angular-eslint / builder :

"lint": {
  "builder": "@angular-eslint/builder:lint",
  "options": {
    "eslintConfig": ".eslintrc.js",
    "tsConfig": [
      "tsconfig.app.json",
      "tsconfig.spec.json",
      "e2e/tsconfig.json"
    ],
    "exclude": [
      "**/node_modules/**"
    ]
  }
},

La configuration de base d'ESLint est prête, vous pouvez maintenant démarrer ESLint avec la commande standard ng lint .

Installer des plugins supplémentaires


Pour installer le plugin pour ESLint, par exemple, pour les tests unitaires de linting dans Angular, vous devez télécharger et ajouter le plugin Jasmine aux paramètres :

npm install eslint-plugin-jasmine --save-dev

Et ajoutez un nouveau bloc de paramètres pour les fichiers avec l'extension * .spec.ts à la propriété "overrides":

overrides: [
  ...,
  {
    files: ['src/**/*.spec.ts', 'src/**/*.d.ts'],
    parserOptions: {
      project: './src/tsconfig.spec.json',
    },
    //   
    extends: ['plugin:jasmine/recommended'],
    //    
    plugins: ['jasmine'],
    env: { jasmine: true },
    //   'no-unused-vars'
    rules: {
      '@typescript-eslint/no-unused-vars': 'off',
    },
  }
],

Par analogie, vous pouvez ajouter d'autres plugins pour différentes extensions de fichier.

Ajout de guides de guide de style


Pour obtenir une plus grande cohérence de la base de code, vous pouvez sélectionner et ajouter les règles de l'un des guides de style populaires à la configuration ESLint:

  • AirBnB : le plus populaire et le plus strict des trois virgules et points-virgules de fin obligatoires.
  • Google : similaire à AirBnB en termes de formatage, mais moins strict, commentaires JSDoc obligatoires.
  • StandartJS : interdit l'utilisation de virgules et de points-virgules de fin.

Choisissez un guide de style plus adapté à votre équipe. Vous pouvez à tour de rôle essayer tous les guides de style sur un grand projet, voir quelles erreurs le linter produit et en fonction de cela faire un choix.

Choisissez une implémentation du guide de style TypeScript car les règles JavaScript peuvent ne pas fonctionner correctement sur TypeScript.

À titre d'exemple, ajoutons le guide de style AirBnB à notre configuration ESLint. Pour ce faire, installez la configuration avec les règles AirBnB pour TypeScript et le plugin avec les règles pour travailler avec la syntaxe d'import / export:

npm install eslint-plugin-import eslint-config-airbnb-typescript --save-dev

Afin de ne pas modifier les paramètres de niveau supérieur, nous allons créer un nouveau bloc de règles dans la propriété "overrides" avec les règles du guide de style AirBnB et l'analyseur TypeScript nécessaire à leur travail:

module.exports = {
  ...,
  overrides: [
    ...,
    {
      files: ['*.ts'],
      extends: [
        'airbnb-typescript/base',
      ],
      parser: '@typescript-eslint/parser',
      parserOptions: {
        ecmaVersion: 2020,
        sourceType: 'module',
      },
    },
  ]
}

Pour ajouter un autre guide de style, vous devez installer un ensemble de règles pour TypeScript, créer un nouveau bloc de règles dans "overrides" avec les règles du guide de style et spécifier l'analyseur nécessaire à leur travail.

Règles de personnalisation


Si vous souhaitez désactiver ou redéfinir certaines règles dans le style du guide, vous pouvez le faire dans la propriété "rules":

module.exports = {
  ...,
  overrides: [
    ...,
    {
      files: ['*.ts'],
      extends: [
        'airbnb-typescript/base',
      ],
      parser: '@typescript-eslint/parser',
      parserOptions: {
        ecmaVersion: 2020,
        sourceType: 'module',
      },
      //  
      rules: {
        'import/no-unresolved': 'off',
        'import/prefer-default-export': 'off',
        'class-methods-use-this': 'off',
        'lines-between-class-members': 'off',
        '@typescript-eslint/unbound-method': [
          'error',
          {
            ignoreStatic: true,
          },
        ],
      },
    },
  ]
}


Configurer Prettier


Pour ajouter Prettier à notre configuration, nous devons installer Prettier lui-même, un plugin avec des règles Prettier, ainsi qu'une configuration qui désactivera toutes les règles qui peuvent entrer en conflit avec Prettier:

npm i prettier eslint-config-prettier eslint-plugin-prettier --save-dev

Dans les "remplacements" dans le bloc avec les règles des fichiers avec l'extension * .ts dans la propriété "étend" tout en bas, ajoutez les règles et les paramètres Prettier:

module.exports = {
  ...,
  overrides: [
    ...,
    {
      files: ['*.ts'],
      extends: [
        //   AirBnB
	'airbnb-typescript/base',
	//   Prettier
	'prettier/@typescript-eslint',
	'plugin:prettier/recommended',
      ],
      ...,
    },
  ]
}

La configuration de Prettier doit toujours se trouver tout en bas de la liste pour remplacer toutes les règles pouvant entrer en conflit avec Prettier.

`prettier / @ typescript-eslint` désactive les règles` @ typescript-eslint`, qui peuvent entrer en conflit avec Prettier, et` plugin: prettier / recommended` fait trois choses:

  • comprend eslint-plugin-prettier,
  • imprime les erreurs de règles plus jolies / plus jolies sur la console comme "erreur",
  • Ajoute des règles de mise en forme prettier eslint-config-prettier.

Config pour Prettier:


Prettier peut formater le code sans aucun paramètre, mais pour correspondre au guide de style AirBnB, vous devez ajouter certains paramètres. Créez le fichier .prettierrc.js à la racine de l'application:

module.exports = {
  trailingComma: "all",
  tabWidth: 2,
  semi: true,
  singleQuote: true,
  bracketSpacing: true,
  printWidth: 100
};

Ces paramètres seront utilisés à la fois par ESLint et Prettier si vous les utilisez pour formater des fichiers en VS Code ou avec la commande:

prettier "--write ."

Configurer le code VS


VS Code peut mettre en évidence et corriger les erreurs trouvées par ESLint lors de l'enregistrement des erreurs. Pour ce faire, téléchargez le plugin ESLint pour VS Code et créez un fichier dans le projet avec les paramètres de l'espace de travail .vscode / settings.json:

  "eslint.validate": [ "javascript", "typescript", "html"],

  "eslint.options": {
    "extensions": [".js", ".ts", "html"]
  },

  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true,
  },

Ici, nous configurons ESLint pour souligner et corriger les erreurs lors de l'enregistrement de fichiers avec les extensions .js, .ts et .html.

Et pour formater un document en utilisant les combinaisons de touches «shift + option + F» ou «shift + alt + F», téléchargez le plugin Prettier pour VS Code et définissez-le comme le formateur par défaut.

Configuration des crochets Git


Les hooks Git sont des scripts que Git invoque sur certains événements: commit, push, recieve.

Avec l'aide d'eux, nous pouvons commencer à linting le code lors de la création d'un commit afin que moins d'erreurs pénètrent dans le pool de requêtes. Pour un travail plus pratique avec des crochets Git, installez Husky , et de vérifier que le code qui est ajouté au commettras (ce qui est utile dans les grands projets où peluchage prend beaucoup de temps) et non pelucheux mis en scène :

npm i husky lint-staged --save-dev

Ajoutez les paramètres de ces plugins à package.json:

"scripts": {
  ...
},
"husky": {
  "hooks": {
    "pre-commit": "lint-staged --relative"
  }
},
"lint-staged": {
  "*.{js,ts}": [
     "eslint --fix"
  ]
},

lint-staged transmet un tableau de fichiers modifiés à la commande appelée. La commande ng lint ne sait pas comment accepter un tableau de fichiers et pour l'utiliser, vous devez écrire un gestionnaire de script supplémentaire. Ou vous pouvez simplement appeler ESLint, comme dans cet exemple. Une telle solution peut être utilisée pour les pré-engagements, et vous pouvez exécuter ng lint pour lint l' ensemble du projet, par exemple, dans le pipeline CI.

résultats


Dans les futures versions d'Angular, ESLint avec les règles de base sera prêt à l'emploi. Maintenant, le processus de configuration ESLint nécessite quelques étapes supplémentaires, ESLint n'a pas d'équivalents pour certaines règles de TSLint et Angular ESLint est toujours en version alpha. Par conséquent, passer à ESLint maintenant ou non dépend de vous.

Cependant, vous devrez configurer vous-même le code guide, les règles supplémentaires, Prettier, Husky et lint-staged. J'espère que cet article vous a aidé à comprendre comment toutes ces choses fonctionnent ensemble.

La configuration des linters peut sembler une tâche triviale, mais elle comporte plusieurs problèmes d'organisation importants: choisir des guides de style, synchroniser diverses solutions entre elles.

Mais le temps consacré à la configuration du linter à l'avenir vous permettra d'économiser considérablement du temps sur le style et la mise en forme du code dans le processus de révision du code, de réduire le nombre d'erreurs qui tombent dans le pool de demandes et d'assurer la cohérence de la base de code.

Un exemple d'implémentation peut être trouvé sur Github .

Si vous trouvez une erreur dans la configuration ou si vous avez des modules complémentaires - écrivez!

Références



All Articles