На прошлой неделе ко мне заёл коллега — джун, который третий час пытался настроить ESLint в проекте. "Оно не работает, и я не понимаю почему". Проблема оказалась в том, что у него стояло три расширения для линтинга, и они конфликтовали друг с другом. Классика.
VSCode linter — это не просто "поставил плагин и забыл". Это целая экосистема инструментов, настроек и подходов. Давайте разберёмся, что к чему, и как сделать так, чтобы линтер помогал, а не бесил.
Статический vs динамический анализ: в чём разница
Начнём с базы. Статический анализ проверяет код без его запуска. Линтер читает исходник, строит абстрактное синтаксическое дерево и ищет паттерны — неиспользуемые переменные, потенциальные null-ссылки, нарушения стиля. Это быстро и безопасно.
Динамический анализ работает во время выполнения. Код запускается, и инструмент следит за тем, что реально происходит — какие функции вызываются, где узкие места, какие данные протекают. Профайлеры, санитайзеры памяти, runtime-чекеры.
Статический анализ ловит около 60% багов до запуска кода. Динамический находит то, что статика пропустила — race conditions, утечки памяти, проблемы с производительностью на реальных данных. Идеально — комбинировать оба подхода.
Линтеры в VSCode — это статический анализ. И этого уже много.
Какие линтеры существуют и что выбрать
Давайте честно: выбор линтера зависит от языка и команды. Но есть инструменты, которые зарекомендовали себя годами.
JavaScript/TypeScript:
- ESLint — де-факто стандарт. Гибкий, куча плагинов, можно настроить под любые требования.
- Prettier — форматирует код, не проверяет логику. Часто идёт в паре с ESLint.
- Biome — новый игрок, написан на Rust, работает быстрее ESLint.
Python:
- Ruff — мой фаворит. Написан на Rust, заменяет Flake8, isort и половину pydocstyle. Работает в 10-100 раз быстрее аналогов.
- Pylint — старый, медленный, но находит больше проблем.
- Flake8 — классика, но уступает Ruff по скорости.
Go:
- golangci-lint — агрегатор множества линтеров, стандарт в Go-сообществе.
Мультиязычные:
- SonarLint — умеет Java, C#, JS, Python, PHP. Хорош, если проект на нескольких языках.
На одном проекте мы перешли с Pylint на Ruff. Время прогона в CI упало с 4 минут до 15 секунд. Команда сначала не поверила, думали, что линтер сломался и ничего не проверяет. Пришлось показать отчёт — те же проблемы, просто быстрее.
Как настроить линтер в VSCode
Короче, разобрались с выбором. Теперь самое интересное — как это заставить работать в редакторе.
Для примера возьмём Python и Ruff. Сначала ставим расширение в VSCode — ищем "Ruff" в маркетплейсе. Потом добавляем конфигурацию в .vscode/settings.json:
{
"[python]": {
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll": "explicit",
"source.organizeImports": "explicit"
},
"editor.defaultFormatter": "charliermarsh.ruff"
},
"ruff.lint.args": [
"--config=pyproject.toml"
]
}
Конфиг самого Ruff лежит в pyproject.toml:
[tool.ruff]
line-length = 88
target-version = "py311"
[tool.ruff.lint]
select = ["E", "F", "W", "I", "N", "UP", "B", "C4"]
ignore = ["E501"]
[tool.ruff.lint.per-file-ignores]
"__init__.py" = ["F401"]
Для JavaScript/TypeScript с ESLint конфигурация похожая. Файл .eslintrc.json:
{
"env": {
"browser": true,
"es2022": true,
"node": true
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"prettier"
],
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint"],
"rules": {
"no-unused-vars": "error",
"@typescript-eslint/no-explicit-any": "warn"
}
}
И в settings.json:
{
"[javascript]": {
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
}
},
"[typescript]": {
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
}
},
"eslint.validate": [
"javascript",
"typescript"
]
}
Главное правило — не дублируйте настройки. Если есть prettier, пусть он занимается форматированием, а ESLint — логикой. Иначе будет война за запятые и отступы.
Сравнение подходов к линтингу
| Подход | Плюсы | Минусы |
|---|---|---|
| Только в VSCode | Мгновенная обратная связь, бесплатно, не блокирует коммиты | Работает только у тех, кто настроил. Джун может закоммитить баг, если забыл поставить плагин |
| Pre-commit hooks | Гарантированно проверяет каждый коммит, блокирует плохой код | Увеличивает время коммита, можно обойти через --no-verify, ломается при конфликтах слияния |
| CI/CD pipeline | Объективная проверка, нельзя обойти, работает для всех | Медленнее — код уже в репозитории, требует настройки CI |
| AI code review | Находит логические баги, а не только стиль, контекстно-зависимое | Может быть шумным, требует качества промптов |
По моему опыту, лучше всего работает комбинация. VSCode linter для мгновенной обратной связи разработчику, pre-commit для базовых проверок, и CI/CD как финальный барьер. AI-ревью добавляется сверху для сложных вещей — архитектурных проблем, уязвимостей, race conditions.
Внедряем линтер в CI/CD
Допустим, локально у всех всё работает. Но это не гарантирует, что в репозиторий не попадёт кривой код. Кто-то не настроил, кто-то закоммитил через веб-интерфейс, кто-то обошёл pre-commit.
В GitLab CI это выглядит так:
lint:
stage: test
image: python:3.11
script:
- pip install ruff
- ruff check --output-format=gitlab .
artifacts:
reports:
codequality: gl-code-quality-report.json
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
Для GitHub Actions:
name: Lint
on: pull_request
jobs:
ruff:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: chartboost/ruff-action@v1
Если честно, большинство команд останавливаются на этом. Поставили линтер, настроили CI, радуются. Но есть проблема — линтер проверяет только стиль и очевидные паттерны. Он не поймёт, что вы забыли обработать ошибку в конкретном месте, или что переменная используется до инициализации в сложной логике.
Тут и приходит время инструментов посерьёзнее.
Что дальше
VSCode linter — это база. Он экономит время на code review, ловит глупые ошибки, наводит порядок в стиле. Но это только первый уровень защиты.
Для реальной безопасности кода нужен многоуровневый подход: линтеры в IDE для мгновенной обратной связи, CI-пайплайны как обязательная проверка, и дополнительный слой — AI code review для поиска логических проблем.
Мы в Distiq как раз занимаемся этим последним уровнем. Бот анализирует каждый MR, находит баги, уязвимости, проблемы с производительностью — то, что обычный линтер пропустит. Подключается за пару минут через webhook, работает с GitLab, GitHub и GitVerse. Российские серверы, данные не уходят за рубеж. Если линтер — это автокоррекция опечаток, то Distiq — это второй глаз опытного разработчика.
