Чем линтер отличается от форматтера?
Вопрос
В чём разница между линтером (ESLint) и форматтером (Prettier), и зачем использовать их вместе?
Короткий ответ
Линтер анализирует AST кода и ищет потенциальные ошибки и нарушения стилевых правил (например, неиспользуемая переменная, == вместо ===), но не решает сам, как код должен выглядеть визуально. Форматтер не ищет ошибок вообще — он детерминированно переформатирует код (отступы, кавычки, переносы строк) по фиксированным правилам, не обсуждаемым по существу.
Подробный ответ
ESLint (линтер):
- Парсит код в AST (абстрактное синтаксическое дерево) и прогоняет по нему набор правил (rules).
- Правила бывают двух родов: находят реальные баги (
no-undef— использование необъявленной переменной,no-unreachable— код послеreturn, exhaustive-deps в React) и следят за стилем/качеством (no-var,eqeqeq, ограничение сложности функций). - Многие правила автоисправляемы (
eslint --fix), но не все — часть требует решения человека (например, "эта переменная не используется — удали её или используй"). - Конфигурируется через
eslint.config.js(flat config) с наборами правил (eslint:recommended,plugin:vue/recommendedи т.д.) и плагинами под конкретный стек.
Prettier (форматтер):
- Не анализирует семантику кода и не ищет багов — он парсит и перепечатывает код в канонической форме.
- Намеренно малонастраиваемый ("opinionated") — минимум опций (ширина строки, кавычки, точка с запятой), чтобы прекратить споры в команде о стиле форматирования в code review.
- Идемпотентен: сколько раз ни запусти — результат один и тот же.
Зачем вместе: ESLint отвечает за "не давай писать плохой/ошибочный код", Prettier — за "весь код в репозитории выглядит одинаково, независимо от того, кто его писал". Если поручить форматирование ESLint-правилам (как раньше делали через eslint-plugin-prettier или стилевые правила вроде indent), они конфликтуют с Prettier и создают лишние ошибки в CI. Современный подход — разделение ответственности: ESLint только для качества кода, Prettier только для форматирования, стилевые правила ESLint отключаются через eslint-config-prettier.
Biome — более новая альтернатива на Rust, объединяющая линтер и форматтер в одном бинарнике без Node.js-зависимостей. Даёт кратно более высокую скорость на больших кодовых базах и не требует синхронизации версий двух отдельных инструментов, хотя экосистема плагинов пока меньше, чем у ESLint.
Пример
// eslint.config.js — линтер: ищет ошибки, не занимается форматированием
import js from '@eslint/js'
export default [
js.configs.recommended,
{
rules: {
'no-unused-vars': 'warn',
eqeqeq: 'error', // требовать === вместо ==
'no-console': 'warn',
},
},
]
// .prettierrc — форматтер: только внешний вид кода
{
"semi": false,
"singleQuote": true,
"printWidth": 100,
"trailingComma": "es5"
}
# типичный пайплайн в CI: сначала линт (баги), потом формат-проверка (стиль)
eslint . --max-warnings=0
prettier --check .
Дополнительные вопросы
- Почему не стоит использовать ESLint-правила для форматирования вместе с Prettier?
- Как настроить husky + lint-staged, чтобы линт и форматирование запускались перед коммитом?
- В чём компромисс перехода с ESLint+Prettier на Biome для большого существующего проекта?