В ESLint 9 повышена минимальная версия Node.js. Поддержка старых рантаймов, которые ещё встречались в экосистеме ESLint 8, прекращена. Основной целевой средой становится актуальная LTS-ветка Node.js, что упрощает поддержку современных возможностей языка и уменьшает количество обходных совместимых реализаций внутри линтера.
При обновлении инфраструктуры CI/CD требуется проверить версии Node.js в пайплайнах, контейнерах Docker и локальных средах разработчиков. Несоответствие версии приводит не к предупреждениям, а к полной невозможности запуска ESLint.
Ключевое архитектурное изменение ESLint 9 заключается в закреплении
flat config как основной и рекомендованной системы конфигурации. Модель
.eslintrc считается устаревающей и постепенно выводится из
обращения.
Flat config опирается на файл eslint.config.js (или
.mjs, .cjs), где конфигурация описывается как
массив объектов:
extends в классическом
виде;Пример структуры:
export default [
{
files: ["**/*.js"],
languageOptions: {
ecmaVersion: 2024,
sourceType: "module"
},
rules: {
"no-unused-vars": "warn"
}
}
];
Переход на flat config меняет саму модель мышления: конфигурация становится декларацией слоёв, а не цепочкой наследования.
.eslintrc как основного механизмаВ ESLint 9 формат .eslintrc официально считается
legacy-подходом. Поддержка сохранена, но с рядом ограничений:
eslint.config.js;Миграция с .eslintrc требует ручного переноса
логики:
extends превращается в импортируемые конфигурационные
объекты;overrides разбиваются на отдельные элементы
массива;env заменяется на
languageOptions.globals.Типичный фрагмент миграции:
import js from "@eslint/js";
export default [
js.configs.recommended,
{
files: ["**/*.js"],
rules: {
eqeqeq: "error"
}
}
];
ESLint 9 усиливает строгую модель загрузки плагинов. Плагины теперь должны быть совместимы с flat config-форматом и явно импортироваться.
Ключевые изменения:
Ранее распространённый стиль:
{
"plugins": ["react"]
}
в flat config трансформируется в:
import react from "eslint-plugin-react";
export default [
{
plugins: {
react
}
}
];
Подобная модель снижает магию разрешения зависимостей и делает граф зависимостей конфигурации прозрачным.
CLI ESLint 9 также адаптирован под новую конфигурационную модель. Поведение утилиты становится более предсказуемым:
eslint.config.js;.eslintrc происходит только
в режиме совместимости;Команда запуска остаётся прежней:
eslint "src/**/*.{js,ts}"
Однако внутренняя логика обработки конфигурации теперь строится вокруг единого дерева flat config, а не цепочки наследуемых JSON-файлов.
Для проектов с крупной историей конфигураций предусмотрен режим совместимости. Он позволяет временно использовать старые конфигурации без полной переписки на flat config.
Типичные ограничения этого режима:
extends.Практика миграции обычно включает постепенный переход:
.eslintrc;ESLint 9 пересматривает механизм поиска конфигурационных файлов. Приоритет становится более строгим:
eslint.config.js / mjs / cjs.eslintrcЭто влияет на монорепозитории, где ранее использовалось несколько конфигурационных файлов в разных директориях. Теперь поведение зависит от явной структуры массива конфигураций, а не от автоматического подъёма конфигураций вверх по дереву директорий.
Часть правил и внутренних API подверглась переработке. Основные изменения касаются:
RuleTester;Плагины, написанные под ESLint 8, могут требовать обновления, особенно если использовали внутренние API, не входящие в публичный контракт.
Глобальные переменные теперь определяются исключительно через
languageOptions.globals. Старый подход через
env сохраняется только в режиме совместимости.
Пример:
export default [
{
languageOptions: {
globals: {
window: "readonly",
document: "readonly"
}
}
}
];
Такое изменение устраняет неоднозначность между средами выполнения и делает конфигурацию более явной.
.eslintignore постепенно теряет значение в пользу
встроенного механизма игнорирования в flat config. Игнорирование теперь
задаётся через отдельные конфигурационные блоки:
export default [
{
ignores: ["dist/**", "node_modules/**"]
}
];
Это объединяет логику конфигурации и исключений в единую систему, устраняя разрозненность настроек.
В экосистеме TypeScript изменения ощущаются сильнее из-за зависимости от ESLint-плагинов и парсеров:
@typescript-eslint/* до версий,
совместимых с ESLint 9;parserOptions.project может
вести себя иначе;Flat config упрощает подключение TypeScript-конфигураций за счёт явного управления языковыми опциями, но требует более аккуратного описания окружения.
Механизм extends заменяется композиционной моделью:
Это устраняет скрытые зависимости между конфигурациями и делает итоговое поведение линтера полностью детерминированным.
ESLint 9 демонстрирует улучшения производительности в сценариях с flat config:
Однако при неправильной миграции (например, чрезмерное дробление конфигурации на мелкие блоки) возможны обратные эффекты, связанные с увеличением количества вычисляемых контекстов.
Flat config предполагает иной подход к архитектуре линтинга:
files и ignores,
а не через дерево директорий.Конфигурация становится ближе к программному коду, чем к декларативному JSON, что требует более строгого контроля версий и структуры проекта.