Что такое линтер: ESLint, Ruff и основы статического анализа
Основы3 минРедакция Innovialabs
Коротко
Линтер читает код без запуска и находит вероятные баги и рискованные приёмы, форматтер только меняет оформление, а проверка типов сверяет типы; настройте все три с минимальными конфигами и запускайте в редакторе, перед коммитом и в CI.
Что делает линтер
Линтер — инструмент, который анализирует исходный код без запуска и сообщает о проблемах: вероятных багах, подозрительных конструкциях и нарушениях договорённых правил. Такой анализ называют статическим.
Что обычно ловит линтер:
- Неиспользуемые переменные и импорты — часто признак опечатки или незаконченного рефакторинга.
- Неопределённые имена — переменная с опечаткой, которая упала бы только при выполнении.
- Недостижимый код после
returnилиthrow. - Рискованные сравнения, например
==вместо===в JavaScript или== Noneвместоis Noneв Python. - Конструкции, склонные к багам — изменяемые значения по умолчанию, пропущенный
await, затенённая переменная. - Соглашения проекта — порядок импортов, именование, запрещённые API.
Линтер находит проблемы за секунды — раньше, чем ревьюер или пользователь.
Линтер, форматтер и проверка типов
| Инструмент | На какой вопрос отвечает | Примеры |
|---|---|---|
| Форматтер | Как код должен выглядеть? Отступы, кавычки, переносы | Prettier, Black, ruff format, gofmt |
| Линтер | Код, скорее всего, ошибочен или нарушает наши правила? | ESLint, Ruff, Pylint, golangci-lint |
| Проверка типов | Сходятся ли типы? | TypeScript (tsc), mypy, Pyright |
Они дополняют друг друга. Форматтер прекращает споры о стиле и меняет только пробелы и разметку. Линтер смотрит на смысл. Проверка типов доказывает, например, что вы нигде не передаёте строку туда, где ждут число. Отдайте стиль форматтеру и отключите стилистические правила в линтере, чтобы они не конфликтовали.
Минимальный конфиг ESLint
Современный ESLint использует «плоский» конфиг — файл eslint.config.js:
import js from "@eslint/js";
export default [
js.configs.recommended,
{
rules: {
"no-unused-vars": "warn",
eqeqeq: "error",
},
},
];
Запуск — npx eslint ., флаг --fix применяет безопасные автоисправления. Для TypeScript добавьте пакет typescript-eslint и его рекомендуемый конфиг; у фреймворков вроде React и Next.js есть свои пресеты.
Минимальный конфиг Ruff
Ruff — быстрый линтер и форматтер для Python, который покрывает правила многих старых инструментов (Flake8, isort, pyupgrade и других). Конфиг лежит в pyproject.toml:
[tool.ruff]
line-length = 88
[tool.ruff.lint]
select = ["E", "F", "I", "B"]
Здесь E — ошибки pycodestyle, F — Pyflakes (неопределённые имена, лишние импорты), I — сортировка импортов, B — flake8-bugbear (конструкции, склонные к багам). Команды:
ruff check .— проверка.ruff check . --fix— проверка с безопасными исправлениями.ruff format .— форматирование, совместимое с Black.
Начните с небольшого набора правил и расширяйте, когда команда привыкнет.
Где их запускать
1. В редакторе. Установите расширение ESLint или Ruff для своего редактора. Проблемы видны прямо при наборе, а форматирование при сохранении держит оформление единым. Здесь обратная связь самая быстрая.
2. Перед коммитом. Инструменты вроде pre-commit (Python) или husky с lint-staged (JavaScript) проверяют только файлы, добавленные в коммит, и плохой код редко попадает в репозиторий.
3. В CI. Последний рубеж, который нельзя обойти локально. Запускайте проверки без автоисправлений и роняйте сборку при ошибках:
# шаг GitHub Actions
- run: npx eslint . --max-warnings=0
- run: ruff check . && ruff format --check .
ruff format --check и prettier --check завершаются ошибкой, если файлы не отформатированы, но не меняют их.
Частые ошибки
- Включить все правила сразу. Команда тонет в предупреждениях и начинает их игнорировать. Начинайте с рекомендуемых пресетов.
- Предупреждения, которые ничего не роняют. Они копятся вечно. Либо сделайте правило ошибкой, либо отключите.
- Массовые отключения комментариями. Изредка
// eslint-disable-next-lineили# noqaс объяснением — нормально; десятки таких мест значат, что правило не подходит. - Конфликт линтера и форматтера. Отключите стилистические правила линтера, когда есть форматтер.
- Внедрение линтера в большой проект одним pull request. Сначала исправьте самые важные правила или применяйте новые правила только к изменённым файлам, затем расширяйте.