Linters & Formatters¶
Automatiser le style de code et détecter les problèmes avant qu'ils n'atteignent la production.
Formatter vs Linter¶
Deux familles d'outils complémentaires, souvent confondues :
- Formatter = correcteur orthographique automatique — il reformate sans poser de question.
- Linter = relecture par un collègue senior — il signale les problèmes, et parfois les corrige.
| Formatter | Linter | |
|---|---|---|
| Action | Reformate automatiquement | Signale (et parfois corrige) |
| Scope | Style uniquement | Bugs, pratiques, complexité |
| Subjectivité | Zéro (règles fixes) | Configurable |
| Exemples | Prettier, Black | ESLint, Ruff |
Pourquoi les deux ?
Un formatter garantit un style uniforme sans débat. Un linter détecte les bugs potentiels, les imports inutilisés, la complexité excessive. Les deux ensemble forment un filet de sécurité complet.
JavaScript / TypeScript¶
eslint-config-prettier
Ce paquet désactive les règles ESLint qui entrent en conflit avec Prettier. Indispensable pour éviter les guerres entre les deux outils.
Créez .eslintrc.json à la racine du projet :
{
"env": {
"browser": true,
"node": true,
"es2021": true
},
"extends": [
"eslint:recommended", // (1)!
"prettier" // (2)!
],
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"rules": {
"no-unused-vars": "warn", // (3)!
"no-console": "warn",
"eqeqeq": "error", // (4)!
"no-var": "error"
}
}
- Règles recommandées par l'équipe ESLint — bon point de départ.
- Désactive les règles de formatage gérées par Prettier.
"warn"au lieu de"error"— signale sans bloquer le build.- Interdit
==au profit de===— évite les conversions implicites.
Créez .prettierrc :
Ajoutez ces scripts à votre package.json :
{
"scripts": {
"lint": "eslint .",
"format": "prettier --write .",
"check": "prettier --check . && eslint ."
}
}
Avant — code mal formaté avec des problèmes :
Après npm run format puis npm run lint --fix :
varremplacé parconst(règleno-var).==remplacé par===(règleeqeqeq).
| Commande | Rôle |
|---|---|
npm run lint | Analyse ESLint (signale les erreurs) |
npx eslint --fix . | Corrige automatiquement ce qui peut l'être |
npm run format | Reformate tout avec Prettier |
npm run check | Vérifie formatage + lint (idéal pour la CI) |
Python¶
Tout se configuré dans pyproject.toml :
[tool.ruff]
line-length = 88 # (1)!
target-version = "py311"
[tool.ruff.lint]
select = [
"E", # pycodestyle errors
"W", # pycodestyle warnings
"F", # pyflakes
"I", # isort (tri des imports)
"B", # flake8-bugbear
"C4", # flake8-comprehensions
"UP", # pyupgrade
]
ignore = ["E501"] # (2)!
[tool.black]
line-length = 88
target-version = ["py311"]
- 88 caractères — la valeur par défaut de Black, Ruff s'y aligne.
- La longueur de ligne est gérée par Black, pas besoin que Ruff la signale aussi.
Avant — code Python avec des problèmes :
import os, sys
import json
import os
def calculer(x,y):
result=x+y
unused_var = 42
return(result)
Après black . puis ruff check --fix . :
- Import dupliqué
ossupprimé, imports triés par isort. - Variable inutilisée
unused_varsupprimée, parenthèses inutiles retirées.
| Commande | Rôle |
|---|---|
ruff check . | Analyse Ruff (signale les erreurs) |
ruff check --fix . | Corrige automatiquement |
black . | Reformate tout avec Black |
black --check . | Vérifie le formatage sans modifier (CI) |
Pre-commit hooks¶
Les hooks pre-commit exécutent automatiquement les linters et formatters à chaque git commit. Plus besoin d'y penser — si le code ne passe pas, le commit est refusé.
Installation¶
Configuration¶
Créez .pre-commit-config.yaml à la racine du projet :
repos:
- repo: local
hooks:
- id: black
name: black
entry: black
language: system
types: [python]
- id: ruff
name: ruff
entry: ruff check --fix
language: system
types: [python]
- id: prettier
name: prettier
entry: prettier --write
language: system
types_or: [javascript, typescript, json, yaml, markdown]
- id: eslint
name: eslint
entry: eslint --fix
language: system
types_or: [javascript, typescript]
Activation¶
À partir de maintenant, chaque git commit déclenche automatiquement les vérifications. Si un fichier est reformaté, le commit est annulé — il suffit de git add les modifications et de recommiter.
Environnement airgap (sans accès Internet)
Utilisez repo: local (comme dans l'exemple ci-dessus) au lieu de repos distants comme https://github.com/pre-commit/mirrors-prettier. Les hooks local utilisent les outils déjà installés sur votre machine — aucun téléchargement nécessaire.
Démonstration
$ git commit -m "feat: add new feature"
black....................................................................Passed
ruff.....................................................................Passed
prettier.................................................................Passed
eslint...................................................................Passed
[main abc1234] feat: add new feature
Récapitulatif des commandes¶
| Outil | Commande | Rôle |
|---|---|---|
| Prettier | prettier --write . | Reformater JS/TS/JSON/YAML/MD |
| Prettier | prettier --check . | Vérifier le formatage (CI) |
| ESLint | eslint . | Analyser le code JS/TS |
| ESLint | eslint --fix . | Corriger automatiquement |
| Black | black . | Reformater le code Python |
| Black | black --check . | Vérifier le formatage (CI) |
| Ruff | ruff check . | Analyser le code Python |
| Ruff | ruff check --fix . | Corriger automatiquement |
| pre-commit | pre-commit install | Activer les hooks |
| pre-commit | pre-commit run --all-files | Exécuter sur tous les fichiers |