Optimiser la Qualité du Code avec les Linters et Formatters (ESLint, Prettier)
Bienvenue dans cette leçon dédiée à l'amélioration de la qualité de votre code grâce à deux outils incontournables de l'écosystème JavaScript : les linters et les formatters. Dans le cadre de notre exploration des Outils et Systèmes de Build Modernes, comprendre et maîtriser ESLint et Prettier est fondamental pour tout développeur frontend souhaitant produire un code propre, maintenable et collaboratif.
1. Introduction : Pourquoi la Qualité du Code est Essentielle
Dans le développement logiciel, la qualité du code n'est pas un luxe, mais une nécessité. Un code de mauvaise qualité peut entraîner des bugs difficiles à débusquer, une maintenabilité laborieuse, des performances médiocres et des conflits incessants au sein des équipes de développement. À l'inverse, un code de haute qualité est :
- Lisible et compréhensible : Facilite la relecture et la prise en main par d'autres développeurs (ou par vous-même dans six mois !).
- Maintenable : Rend les modifications, les ajouts de fonctionnalités et la correction de bugs plus rapides et moins risqués.
- Fiable : Réduit la probabilité d'introduire des erreurs.
- Collaboratif : Assure une cohérence de style et de pratiques entre les membres d'une équipe, évitant les guerres de "tabs vs spaces" ou de "semicolon vs no semicolon".
C'est là qu'interviennent les linters et les formatters. Ce sont des outils d'automatisation qui agissent comme des "garde-fous" pour garantir que votre code respecte des standards de qualité et de style définis.
2. Qu'est-ce qu'un Linter ? (Focus sur ESLint)
2.1 Définition et Philosophie
Un linter est un outil d'analyse statique du code. Il parcourt votre code source avant même son exécution pour identifier des problèmes potentiels qui pourraient être des erreurs, des bugs, des mauvaises pratiques de programmation ou des incohérences de style.
La philosophie derrière les linters est de prévenir les problèmes et de renforcer les bonnes pratiques. Ils agissent comme un professeur attentif qui vous signale où vous pourriez vous tromper, vous apprenant ainsi à mieux coder.
2.2 ESLint : Le Linter Indispensable pour JavaScript/TypeScript
ESLint est le linter de référence pour l'écosystème JavaScript et TypeScript (via des plugins). Il est extrêmement flexible et configurable, permettant aux équipes de définir leurs propres règles ou d'utiliser des ensembles de règles populaires.
Fonctionnalités clés d'ESLint :
- Détection d'erreurs potentielles : Variables non définies, variables déclarées mais non utilisées (
no-unused-vars), accès à des propriétés inexistantes, boucles infinies potentielles, etc. - Application de bonnes pratiques : Force l'utilisation de
constouletplutôt quevar, interdit l'utilisation deeval(), recommande des structures conditionnelles claires, etc. - Règles de style (bien que Prettier soit plus adapté pour cela) : Vérifie l'indentation, l'utilisation des points-virgules, des guillemets, etc. (nous verrons comment déléguer cette partie à Prettier).
- Support des plugins : Permet d'étendre ESLint pour supporter des frameworks (React, Vue, Angular), TypeScript, des syntaxes spécifiques (JSX) ou des environnements spécifiques (Node.js, navigateurs).
- Configuration flexible : Chaque règle peut être configurée comme un avertissement (
warn), une erreur (error) ou désactivée (off).
2.3 Mise en Place et Configuration d'ESLint
2.3.1 Installation
Pour installer ESLint dans votre projet, utilisez npm ou yarn :
npm install eslint --save-dev
# ou
yarn add eslint --dev
2.3.2 Initialisation
Une fois installé, vous pouvez initialiser ESLint pour créer son fichier de configuration :
npx eslint --init
Cette commande vous posera une série de questions pour configurer votre projet :
- Comment souhaitez-vous utiliser ESLint ? (To check syntax, find problems, and enforce style)
- Quel type de modules votre projet utilise-t-il ? (ES Modules)
- Quel framework utilisez-vous ? (React, Vue, None)
- Utilisez-vous TypeScript ? (Yes/No)
- Où votre code s'exécute-t-il ? (Browser, Node)
- Comment souhaitez-vous définir un style pour votre projet ? (Use a popular style guide - Airbnb, Standard, Google / Answer questions about your style / Inspect your JavaScript file(s))
- Quel format souhaitez-vous pour votre fichier de configuration ? (JavaScript, YAML, JSON)
2.3.3 Le Fichier .eslintrc.js
Après l'initialisation, un fichier de configuration comme .eslintrc.js (ou .eslintrc.json, etc.) sera créé à la racine de votre projet. Voici un exemple simple :
// .eslintrc.js
module.exports = {
env: {
browser: true,
es2021: true,
node: true,
},
extends: [
'eslint:recommended', // Règles recommandées par ESLint
'plugin:react/recommended', // Règles recommandées pour React
'plugin:@typescript-eslint/recommended', // Règles recommandées pour TypeScript
],
parser: '@typescript-eslint/parser', // Parseur pour TypeScript
parserOptions: {
ecmaFeatures: {
jsx: true, // Support JSX
},
ecmaVersion: 'latest',
sourceType: 'module',
},
plugins: [
'react',
'@typescript-eslint',
],
rules: {
// Exemples de règles personnalisées ou modifiées
'indent': ['error', 2], // Indentation à 2 espaces (erreur)
'linebreak-style': ['error', 'unix'], // Style de fin de ligne Unix (LF)
'quotes': ['error', 'single'], // Utilisation des guillemets simples (erreur)
'semi': ['error', 'always'], // Nécessite des points-virgules (erreur)
'no-unused-vars': ['warn', { 'argsIgnorePattern': '^_' }], // Avertit des variables non utilisées, sauf celles qui commencent par '_'
'react/prop-types': 'off', // Désactive la vérification des propTypes de React (si on utilise TypeScript)
},
settings: {
react: {
version: 'detect', // Détecte automatiquement la version de React
},
},
};
Explication des sections clés :
env: Définit les environnements d'exécution globaux.extends: Permet d'hériter des configurations existantes (très utile pour les style guides populaires).parseretparserOptions: Spécifient comment ESLint doit analyser votre code (important pour TypeScript, JSX, ou les dernières versions d'ECMAScript).plugins: Ajoutent des fonctionnalités ou des ensembles de règles supplémentaires (pour React, TypeScript, etc.).rules: Permet de personnaliser, d'activer ou de désactiver des règles spécifiques et de définir leur niveau de sévérité (off,warn,error).
2.3.4 Lancement d'ESLint
Vous pouvez exécuter ESLint sur votre code depuis la ligne de commande :
npx eslint your-file.js
# ou pour l'ensemble du projet
npx eslint . --ext .js,.jsx,.ts,.tsx
Vous pouvez ajouter un script à votre package.json :
"scripts": {
"lint": "eslint . --ext .js,.jsx,.ts,.tsx",
"lint:fix": "eslint . --ext .js,.jsx,.ts,.tsx --fix"
}
Puis lancer npm run lint ou npm run lint:fix. L'option --fix tente de corriger automatiquement les problèmes qui peuvent l'être.
2.4 Exemple Pratique d'ESLint
Considérons le fichier src/bad-code.js suivant :
// src/bad-code.js
var maVariable = "Hello";
const autreVariable = "World";
function greet(name) {
console.log('Salut, ' + name + '!');
maVariable = "Modified"; // Changer une variable 'var'
}
greet("Dev");
if (true) {
let z = 10;
}
console.log(z); // Variable z non définie ici
Si nous exécutons ESLint avec une configuration standard (par exemple, eslint:recommended et quelques règles de style), nous pourrions obtenir des avertissements/erreurs comme ceux-ci :
/src/bad-code.js
1:1 error 'var' not allowed. Use 'let' or 'const' instead no-var
1:5 warning 'maVariable' is assigned a value but never used no-unused-vars
6:1 error 'maVariable' is already defined no-redeclare
6:1 warning 'maVariable' is assigned a value but never used no-unused-vars
12:13 error 'z' is not defined no-undef
3:13 error Expected a single quote for string 'Salut, ' + name + '!'. quotes
3:13 error Strings must use backticks or template literals quotes
ESLint nous a signalé plusieurs problèmes :
no-var:maVariableest déclarée avecvar, qui est souvent déconseillée au profit deletouconst.no-unused-vars:maVariableest déclarée mais pas lue après sa dernière affectation.no-undef: La variablezest utilisée en dehors de son scope.quotes: Problème de guillemets (si configuré pour des guillemets simples ou des template literals).
Ces alertes nous aident à améliorer la robustesse et la clarté du code.
3. Qu'est-ce qu'un Formatter ? (Focus sur Prettier)
3.1 Définition et Philosophie
Un formatter est un outil qui réécrit le code pour s'assurer qu'il respecte un style cohérent et prédéfini. Contrairement au linter qui signales les problèmes, le formatter les corrige automatiquement en réarrangeant le code.
La philosophie de Prettier est d'être opinionné : il prend la plupart des décisions stylistiques pour vous, éliminant ainsi les discussions infinies sur le style au sein des équipes. Vous configurez quelques options de base (guillemets simples/doubles, point-virgule oui/non, largeur de ligne) et Prettier s'occupe du reste.
3.2 Prettier : Le Formatter Universel
Prettier est devenu le standard de facto pour le formatage de code dans de nombreux écosystèmes, et particulièrement en JavaScript/TypeScript.
Fonctionnalités clés de Prettier :
- Formatage automatique : Indentation, espacement, retours à la ligne, points-virgules, guillemets, parenthèses... Prettier gère tous les aspects de la mise en forme.
- Opinionné : Il y a peu d'options de configuration, ce qui réduit la friction et garantit une grande uniformité.
- Support multi-langages : JavaScript (avec JSX), TypeScript, Flow, CSS, SCSS, Less, HTML, Vue, Angular, JSON, GraphQL, Markdown, YAML...
- Intégration profonde : Extensions pour la plupart des éditeurs de code (VS Code, Sublime Text, Atom, WebStorm), intégration avec les hooks Git et les systèmes de CI/CD.
3.3 Mise en Place et Configuration de Prettier
3.3.1 Installation
npm install prettier --save-dev
# ou
yarn add prettier --dev
3.3.2 Le Fichier .prettierrc (ou .prettierrc.json)
Prettier peut être configuré avec un fichier .prettierrc, .prettierrc.json, .prettierrc.js, etc., à la racine de votre projet.
// .prettierrc.json
{
"printWidth": 80, // Longueur maximale d'une ligne avant de la couper
"tabWidth": 2, // Nombre d'espaces par tabulation
"useTabs": false, // Utiliser des espaces au lieu de tabulations
"semi": true, // Ajouter un point-virgule à la fin des instructions
"singleQuote": true, // Utiliser des guillemets simples au lieu de doubles
"trailingComma": "es5", // Ajouter des virgules de fin pour les objets et tableaux (es5, all, none)
"bracketSpacing": true, // Ajouter des espaces entre les accolades d'objet
""arrowParens"": "always", // Toujours inclure les parenthèses autour des paramètres des fonctions fléchées
"jsxSingleQuote": false // Utiliser des guillemets simples en JSX (true) ou doubles (false)
}
3.3.3 Lancement de Prettier
Vous pouvez formater des fichiers ou des répertoires depuis la ligne de commande :
npx prettier --write "src/**/*.js" # Formate tous les fichiers JS dans le dossier src
npx prettier --write . # Formate tous les fichiers du projet (selon les .prettierignore)
Il est courant d'ajouter des scripts à package.json :
"scripts": {
"format": "prettier --write ."
}
Puis lancez npm run format.
3.4 Exemple Pratique de Prettier
Considérons le fichier src/unformatted.js suivant :
// src/unformatted.js
const maDonnee = { a: 1, b: 2 };
function calcul(x,y)
{
return x+y;
}
let result = calcul( maDonnee.a ,maDonnee.b ); console.log( result )
Après avoir exécuté npx prettier --write src/unformatted.js avec la configuration .prettierrc.json ci-dessus, le fichier sera transformé en :
// src/unformatted.js
const maDonnee = { a: 1, b: 2 };
function calcul(x, y) {
return x + y;
}
let result = calcul(maDonnee.a, maDonnee.b);
console.log(result);
Prettier a automatiquement :
- Corrigé l'indentation.
- Supprimé les espaces superflus.
- Ajouté un point-virgule à la fin du
console.log. - Placé l'accolade ouvrante de la fonction sur la même ligne.
- Ajouté des espaces autour des opérateurs et des parenthèses.
- Géré les retours à la ligne.
Ces transformations garantissent un style uniforme et éliminent toute discussion de style.
4. La Synergie : ESLint et Prettier Ensemble
ESLint et Prettier ne sont pas des outils concurrents, mais complémentaires.
- ESLint se concentre sur la qualité structurelle et sémantique du code : prévenir les bugs, appliquer les bonnes pratiques, identifier les problèmes potentiels.
- Prettier se concentre sur la qualité esthétique et syntaxique : maintenir un style de code cohérent et lisible pour tous.
4.1 Gérer les Conflits de Style
Le principal défi de l'utilisation conjointe d'ESLint et Prettier est que ESLint a aussi des règles de style. Sans précaution, Prettier pourrait formater le code d'une manière qu'ESLint jugerait incorrecte, créant des avertissements/erreurs inutiles.
La solution est de désactiver toutes les règles de style d'ESLint qui peuvent entrer en conflit avec Prettier. Pour cela, nous utilisons des plugins spécifiques :
eslint-config-prettier: Désactive les règles ESLint qui sont incompatibles ou redondantes avec Prettier.eslint-plugin-prettier: Intègre Prettier directement dans ESLint, permettant à ESLint de signaler les problèmes de formatage que Prettier n'a pas corrigés (et même de les corriger aveceslint --fix).
4.1.1 Installation des plugins de synergie
npm install eslint-config-prettier eslint-plugin-prettier --save-dev
# ou
yarn add eslint-config-prettier eslint-plugin-prettier --dev
4.1.2 Configuration de .eslintrc.js
Ajoutez plugin:prettier/recommended à votre tableau extends en dernière position. Cela garantit qu'il désactive correctement les règles précédentes.
// .eslintrc.js (exemple avec React et TypeScript)
module.exports = {
// ... autres configurations ...
extends: [
'eslint:recommended',
'plugin:react/recommended',
'plugin:@typescript-eslint/recommended',
'plugin:prettier/recommended', // TOUJOURS EN DERNIÈRE POSITION
],
plugins: [
'react',
'@typescript-eslint',
'prettier' // Le plugin Prettier
],
rules: {
// Les règles ESLint qui pourraient entrer en conflit sont désactivées par 'plugin:prettier/recommended'
// Vous pouvez toujours ajouter vos règles ESLint non-stylistiques ici.
// 'no-unused-vars': ['warn', { 'argsIgnorePattern': '^_' }],
// 'prettier/prettier': 'error' // Active la règle Prettier dans ESLint. Indique les non-conformités Prettier comme des erreurs.
},
// ... autres configurations ...
};
Avec cette configuration, ESLint va :
- Vérifier les problèmes de code (bugs, mauvaises pratiques) via ses règles et celles des plugins (
react,@typescript-eslint). - Désactiver toutes les règles de style qui sont gérées par Prettier.
- Utiliser Prettier lui-même pour signaler (et potentiellement corriger via
--fix) les problèmes de formatage.
4.2 Intégration au Workflow de Développement
Pour maximiser l'efficacité de ces outils, intégrez-les à chaque étape de votre workflow :
4.2.1 Intégration IDE (VS Code)
C'est l'intégration la plus immédiate et la plus gratifiante. Installez les extensions suivantes dans VS Code :
- ESLint (par Dirk Baeumer)
- Prettier - Code formatter (par Prettier)
Configurez VS Code pour formater à la sauvegarde et utiliser Prettier comme formateur par défaut :
// .vscode/settings.json
{
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
Désormais, chaque fois que vous sauvegardez un fichier, Prettier le formatera, et ESLint corrigera automatiquement les problèmes qu'il peut résoudre (source.fixAll.eslint).
4.2.2 Hooks Git (Husky, lint-staged)
Pour garantir que seul du code de qualité est commité, utilisez les Git hooks.
- Husky : Un outil qui facilite la configuration des hooks Git.
- lint-staged : Permet d'exécuter des linters et formatters uniquement sur les fichiers qui sont staged (ajoutés à l'index de Git) avant un commit.
- Installation :
npm install husky lint-staged --save-dev - Configuration de Husky :
Ajoutez la configuration Husky dans votre
package.jsonou un fichier.huskyrc.json.// package.json { "name": "my-app", "version": "0.1.0", "private": true, "scripts": { "prepare": "husky install" // Important pour activer Husky après installation }, "devDependencies": { "husky": "^8.0.0", "lint-staged": "^13.0.0" }, "husky": { "hooks": { "pre-commit": "lint-staged" // Exécute lint-staged avant chaque commit } }, "lint-staged": { "*.{js,jsx,ts,tsx}": "eslint --cache --fix", "*.{js,jsx,ts,tsx,css,md,json}": "prettier --write" } } - Activation de Husky :
Exécutez
npm install(ouyarn) puisnpm run prepare(ou lanceznpx husky installmanuellement).
Maintenant, à chaque git commit, lint-staged va :
- Exécuter
eslint --fixsur tous les fichiers JavaScript/TypeScript mis en scène. - Exécuter
prettier --writesur tous les fichiers concernés (JS, TS, CSS, MD, JSON, etc.) mis en scène.
Si ESLint trouve des problèmes qu'il ne peut pas corriger, le commit sera bloqué, forçant le développeur à résoudre les problèmes de qualité.
4.2.3 Intégration CI/CD
Dans un environnement d'intégration continue/déploiement continu (CI/CD), ajoutez une étape pour exécuter les linters et formatters (sans l'option --fix pour ESLint, car le but est de vérifier, pas de corriger) avant de construire et déployer l'application.
Exemple de script CI (dans GitHub Actions, GitLab CI, Jenkins, etc.) :
# Exemple pour GitHub Actions
name: Code Quality Check
on:
pull_request:
branches:
- main
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies
run: npm ci
- name: Run ESLint
run: npm run lint
- name: Check Prettier Formatting
run: npx prettier --check .
Si ces commandes échouent (c'est-à-dire que des erreurs ESLint non corrigées subsistent ou que le code n'est pas formaté selon Prettier), le pipeline CI échoue, empêchant la fusion d'un code de mauvaise qualité.
5. Conclusion et Résumé
Les linters comme ESLint et les formatters comme Prettier sont des outils indispensables dans le développement frontend moderne. Ils automatisent la détection et la correction de problèmes de qualité et de style, vous permettant de :
- Gagner du temps : Fini les débats sans fin sur le style, les revues de code fastidieuses pour la syntaxe.
- Réduire les bugs : Les linters détectent des erreurs potentielles avant même l'exécution.
- Améliorer la maintenabilité : Un code cohérent est plus facile à lire et à modifier.
- Faciliter la collaboration : Tout le monde écrit dans le même "langage" stylistique.
- Augmenter la fiabilité : Garantit un niveau de qualité minimal avant chaque commit ou déploiement.
En les intégrant judicieusement à votre environnement de développement (IDE), à vos hooks Git et à votre pipeline CI/CD, vous construirez un workflow robuste qui garantit une haute qualité de code de manière continue. Maîtriser ces outils est un pas de géant vers une productivité accrue et une meilleure expérience de développement.