11.3 — Outils statiques
🎯 Objectif : prévenir les bugs avant la prod en lisant le code statiquement. Linter, formatter, type-checker — la triade indispensable 2026.
À l'issue de cet axe, tu sauras :
- Configurer ESLint v9 (flat config) avec Prettier
- Choisir entre ESLint+Prettier et Biome
- Activer TypeScript strict + noUncheckedIndexedAccess
- Lancer PHPStan ou Psalm sur du PHP
- Configurer Ruff + mypy sur Python
- Mettre lint + typecheck en CI bloquante
Confirmé
Linter, formatter, type-checker
Section intitulée « Linter, formatter, type-checker »3 outils complémentaires qui analysent ton code sans l’exécuter :
| Outil | Détecte |
|---|---|
| Linter | Bugs probables, mauvaises pratiques, code mort |
| Formatter | Indentation, espaces, virgules — l’apparence |
| Type-checker | Incohérences de types |
Tu veux les trois dans tes projets sérieux. Lancés en pre-commit + CI.
Linter + formatter — l’écosystème JS/TS
Section intitulée « Linter + formatter — l’écosystème JS/TS »Option 1 — ESLint v9 + Prettier (le standard)
Section intitulée « Option 1 — ESLint v9 + Prettier (le standard) »ESLint v9 (sortie 2024) introduit la flat config (eslint.config.js) qui remplace .eslintrc.
npm install -D eslint @eslint/js typescript-eslint prettierimport js from '@eslint/js';import tseslint from 'typescript-eslint';
export default tseslint.config( js.configs.recommended, ...tseslint.configs.strict, { rules: { '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }], 'no-console': ['warn', { allow: ['warn', 'error'] }], }, });{ "semi": true, "singleQuote": true, "trailingComma": "es5", "printWidth": 100, "arrowParens": "always"}// package.json — scripts{ "scripts": { "lint": "eslint .", "lint:fix": "eslint . --fix", "format": "prettier --write .", "typecheck": "tsc --noEmit", "check": "pnpm lint && pnpm format --check && pnpm typecheck" }}Option 2 — Biome (l’outsider en 2026)
Section intitulée « Option 2 — Biome (l’outsider en 2026) »Biome = un seul binaire Rust qui fait linter + formatter + import organizer. 10-100× plus rapide qu’ESLint + Prettier.
npm install -D @biomejs/biomenpx biome init{ "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", "linter": { "enabled": true, "rules": { "recommended": true } }, "formatter": { "enabled": true, "indentStyle": "space", "indentWidth": 2 }}npx biome check # lint + format checknpx biome check --write # corrige✅ Ultra-rapide, un seul outil. ❌ Moins de règles que ESLint, certains plugins React/Vue/Astro pas encore au niveau.
Verdict 2026 : ESLint v9 + Prettier reste le défaut pour son écosystème. Biome gagne du terrain sur les projets qui priorisent la vitesse de feedback. Tu peux migrer plus tard.
Plugins essentiels (ESLint)
Section intitulée « Plugins essentiels (ESLint) »| Plugin | Rôle |
|---|---|
typescript-eslint | Typescript-specific rules |
eslint-plugin-react | React |
eslint-plugin-react-hooks | Détecte les violations de règles des hooks |
eslint-plugin-jsx-a11y | Accessibilité JSX |
eslint-plugin-import | Imports propres |
eslint-plugin-vitest | Anti-patterns de tests |
eslint-plugin-tailwindcss | Conventions Tailwind |
TypeScript strict — le minimum 2026
Section intitulée « TypeScript strict — le minimum 2026 »{ "compilerOptions": { "strict": true, "noUncheckedIndexedAccess": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "noUnusedLocals": true, "noUnusedParameters": true }}strict: true active 8 vérifications d’un coup :
noImplicitAnystrictNullChecks(le plus important —null/undefinedexplicites)strictFunctionTypesstrictBindCallApplystrictPropertyInitializationnoImplicitThisuseUnknownInCatchVariablesalwaysStrict
noUncheckedIndexedAccess ajoute | undefined quand tu accèdes à arr[0] ou obj[key]. Plus sûr.
// Avec noUncheckedIndexedAccessconst arr = [1, 2, 3];const first = arr[0]; // type: number | undefinedconsole.log(first.toFixed(2)); // ❌ erreur — peut être undefined
// Tu DOIS gérer le undefined :if (first !== undefined) console.log(first.toFixed(2));tsc --noEmit en CI
Section intitulée « tsc --noEmit en CI »- run: pnpm typecheck # tsc --noEmitBloque le merge si une erreur TS apparaît.
Outils statiques par langage
Section intitulée « Outils statiques par langage »Python — Ruff + mypy
Section intitulée « Python — Ruff + mypy »Ruff remplace Black + isort + Flake8 + pyupgrade + plein d’autres en un seul binaire Rust.
uv add --dev ruff mypy[tool.ruff]line-length = 100target-version = "py312"
[tool.ruff.lint]select = ["E", "F", "I", "B", "W", "UP"] # bug-prone, style, imports, etc.
[tool.ruff.format]quote-style = "double"
[tool.mypy]strict = truepython_version = "3.12"uv run ruff check . # lintuv run ruff format . # formatuv run mypy . # type-checkPHP — PHPStan ou Psalm
Section intitulée « PHP — PHPStan ou Psalm »PHPStan analyse statiquement le code PHP, détecte des bugs de types impossibles à exécuter.
composer require --dev phpstan/phpstanparameters: level: 8 # 0 = laxiste, 9 = max strict paths: - src excludePaths: - testsvendor/bin/phpstan analyseNiveau 8-9 = équivalent TypeScript strict. Permet d’attraper :
- Méthodes appelées sur
null. - Types incohérents.
- Code mort.
- Mauvaises annotations docblock.
Laravel — Larastan + Pint
Section intitulée « Laravel — Larastan + Pint »composer require --dev larastan/larastan laravel/pintPint est un formatter spécifique Laravel (basé PHP-CS-Fixer). Larastan étend PHPStan avec la connaissance Laravel (Eloquent, Facades).
Symfony — PHPStan + PHP-CS-Fixer
Section intitulée « Symfony — PHPStan + PHP-CS-Fixer »Combo classique. Symfony fournit aussi symfony/phpstan-extension pour les helpers.
Pre-commit hooks — déléguer à la machine
Section intitulée « Pre-commit hooks — déléguer à la machine »Pour forcer lint + format avant commit, sans dépendre de la discipline :
lint-staged + husky
Section intitulée « lint-staged + husky »npm install -D husky lint-stagednpx husky init{ "lint-staged": { "*.{ts,tsx,js,jsx}": ["eslint --fix", "prettier --write"], "*.{json,md,css}": ["prettier --write"] }}npx lint-stagedÀ chaque git commit, seuls les fichiers stagés sont lintés/formatés. Rapide même sur gros repo.
Pre-commit (Python, multi-langages)
Section intitulée « Pre-commit (Python, multi-langages) »pre-commit gère pareil pour Python :
repos: - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.8.4 hooks: - id: ruff args: [--fix] - id: ruff-formatuv run pre-commit installCI bloquante
Section intitulée « CI bloquante »name: CIon: [push, pull_request]
jobs: lint-and-test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: { node-version: '24' } - run: npm ci - run: npm run lint - run: npm run typecheck - run: npm run test -- --coverage - run: npm run buildChaque PR doit passer lint + typecheck + tests + build avant merge. Configuré en branch protection sur GitHub : on ne peut pas merger si la CI échoue.
Outils additionnels utiles
Section intitulée « Outils additionnels utiles »semgrep — pattern-based static analysis
Section intitulée « semgrep — pattern-based static analysis »Semgrep scanne du code multi-langage avec des règles type “regex sémantique”. Détecte des bugs de sécu et anti-patterns :
npx semgrep --config=auto .gitleaks / trufflehog — détecter les secrets
Section intitulée « gitleaks / trufflehog — détecter les secrets »npx gitleaks detect --no-gitÀ mettre en pre-commit + CI pour empêcher de commit accidentellement une clé API.
dependabot / renovate — mises à jour des deps
Section intitulée « dependabot / renovate — mises à jour des deps »GitHub Dependabot ouvre automatiquement des PR quand une dépendance a une nouvelle version (sécurité ou minor). Renovate est l’alternative open source plus configurable.
sonarqube / codeclimate — scoring qualité globale
Section intitulée « sonarqube / codeclimate — scoring qualité globale »Pour les projets enterprise, ces SaaS notent ton repo selon : couverture, duplication, complexité cyclomatique, tech debt.
Auto-évaluation
Section intitulée « Auto-évaluation »Pour aller plus loin
Section intitulée « Pour aller plus loin »- ESLint Documentation — eslint.org
- Biome — biomejs.dev
- Prettier — prettier.io
- typescript-eslint — typescript-eslint.io
- Ruff — docs.astral.sh/ruff
- PHPStan — phpstan.org
- pre-commit — pre-commit.com
Suite : 11.4 — Documentation — README, ADR, OpenAPI, Storybook.