Aller au contenu

ESLint : configuration

Un export par défaut : un tableau de blocs de configuration, évalués dans l’ordre.

import js from '@eslint/js';
import globals from 'globals';
export default [
// 1. Fichiers ignorés (bloc contenant seulement « ignores »)
{ ignores: ['dist/', 'coverage/', '.astro/', '.next/'] },
// 2. Règles recommandées
js.configs.recommended,
// 3. Réglages du projet
{
files: ['src/**/*.js'],
languageOptions: { globals: { ...globals.browser } },
rules: { 'no-console': 'warn' },
},
// 4. Surcharge pour les tests
{
files: ['**/*.test.js'],
languageOptions: { globals: { ...globals.node } },
rules: { 'no-console': 'off' },
},
];
Clé Rôle
files Motifs des fichiers concernés par ce bloc
ignores Motifs exclus (dans un bloc sans autre clé : ignorés globalement)
languageOptions ecmaVersion, sourceType, globals, parser, parserOptions
plugins Plugins utilisés (objet { nom: plugin })
rules Règles et niveaux
settings Données partagées par les règles (version de React…)
linterOptions reportUnusedDisableDirectives, noInlineConfig

Règle de fusion : pour un même fichier, les blocs dont files correspond s’appliquent dans l’ordre ; le dernier l’emporte. Mettre les réglages généraux d’abord, les exceptions ensuite.

ESLint 9 analyse **/*.js, **/*.mjs, **/*.cjs. Pour d’autres extensions (.ts, .jsx, .astro), les inclure dans files d’un bloc (voir TypeScript et React, Astro et Next.js).

{ files: ['**/*.{js,jsx,ts,tsx}'], rules: { /* ... */ } }
export default [
{ ignores: ['dist/**', 'coverage/**', '**/*.min.js', 'public/vendor/'] },
// ...
];

Un ignores placé dans un bloc avec d’autres clés ne s’applique qu’à ce bloc. Pour ignorer globalement, utiliser un bloc qui ne contient que ignores. La fonction globalIgnores (disponible dans les versions récentes) rend l’intention explicite :

import { defineConfig, globalIgnores } from 'eslint/config';
export default defineConfig([
globalIgnores(['dist/', 'coverage/']),
// ...
]);

defineConfig apporte aussi la vérification de types et la syntaxe extends dans un bloc ; elle dépend de la version d’ESLint installée.

import globals from 'globals';
{
languageOptions: {
globals: {
...globals.browser, // window, document, fetch…
...globals.node, // process, Buffer, __dirname…
...globals.vitest, // describe, it, expect (si globals: true)
},
},
}

Le fichier de configuration lui-même s’exécute dans Node.js : si on veut l’analyser avec des globales Node.js, un bloc files: ['eslint.config.js'] lui donne globals.node.

Jeux prêts à l’emploi :

Jeu Contenu
js.configs.recommended Règles qui détectent des erreurs probables (recommandé)
js.configs.all Toutes les règles (trop strict en pratique)
typescript-eslint : recommended, strict, stylistic Pour TypeScript (voir TypeScript)

Règles ajoutées couramment :

rules: {
eqeqeq: ['error', 'always'], // === et !==
'prefer-const': 'error', // const quand la variable n'est pas réassignée
'no-var': 'error',
'no-unused-vars': ['error', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }],
'no-console': ['warn', { allow: ['warn', 'error'] }],
'no-shadow': 'error', // variable qui masque une variable extérieure
'no-throw-literal': 'error', // throw de vraies erreurs
'no-return-await': 'off',
'require-await': 'warn', // fonction async sans await
'no-await-in-loop': 'warn',
curly: ['error', 'multi-line'], // accolades pour les blocs sur plusieurs lignes
'no-restricted-imports': ['error', { patterns: ['../../*'] }],
}

Chaque règle est documentée sur eslint.org/docs/latest/rules/. Ne pas empiler des règles de style (indentation, guillemets) : c’est le rôle de Prettier (Prettier et éditeur).

Un plugin ajoute des règles :

Fenêtre de terminal
npm install -D eslint-plugin-import eslint-plugin-n eslint-plugin-unicorn
import importPlugin from 'eslint-plugin-import';
export default [
{
files: ['**/*.js'],
plugins: { import: importPlugin },
rules: {
'import/no-duplicates': 'error',
'import/order': ['warn', { 'newlines-between': 'always' }],
},
},
];

Les règles d’un plugin se nomment préfixe/nom-de-règle (le préfixe est la clé de l’objet plugins). Beaucoup de plugins proposent des configurations prêtes à l’emploi (plugin.configs.recommended). Choisir peu de plugins, bien maintenus, compatibles avec ESLint 9 et la configuration à plat.

{
settings: { react: { version: 'detect' } },
}
export default [
// règles générales
{ files: ['src/**/*.js'], rules: { 'no-console': 'error' } },
// le dossier scripts/ peut écrire dans la console
{ files: ['scripts/**'], rules: { 'no-console': 'off' } },
// les tests acceptent des fonctions sans await
{ files: ['**/*.test.js'], rules: { 'require-await': 'off' } },
];

ESLint 9 cherche eslint.config.js depuis le dossier courant vers la racine. Pour une configuration par paquet, exécuter ESLint depuis le dossier concerné, ou utiliser un seul fichier racine avec des blocs files: ['paquets/api/**'].

eslint/base.js
import js from '@eslint/js';
export const base = [js.configs.recommended, { rules: { eqeqeq: 'error' } }];
// eslint/node.js
import globals from 'globals';
export const node = [
{ files: ['src/server/**'], languageOptions: { globals: globals.node } },
];
// eslint.config.js
import { base } from './eslint/base.js';
import { node } from './eslint/node.js';
export default [...base, ...node];
Fenêtre de terminal
npx eslint --print-config src/app.js | head -50 # configuration effective
npx eslint --debug src/app.js 2>&1 | grep -i config # détail de la résolution
npx eslint --inspect-config # inspecteur graphique (versions récentes)
Symptôme Piste
Une règle ne s’applique pas à un fichier files du bloc ne correspond pas (extension), bloc plus ancien écrasé par un bloc plus récent
Definition for rule 'x' not found Plugin non déclaré dans plugins, mauvais préfixe
Le fichier est ignoré sans raison Motif de ignores trop large, ou fichier dans .gitignore (non pris en compte automatiquement)
You have used a rule which requires type information Règle de TypeScript nécessitant parserOptions.project (voir TypeScript)
TypeError: Key "rules": Key "x": Could not find rule Version de plugin incompatible avec la version d’ESLint
Les globales ne sont pas connues languageOptions.globals du bon bloc
Configuration trop lourde Réduire les plugins, utiliser --cache

Ubuntu 24.04 et 26.04 : différences à connaître

Section intitulée « Ubuntu 24.04 et 26.04 : différences à connaître »

Aucune.