Часто полезный код портится из-за мелких ошибок, которые можно было поймать ещё до коммита. В этой статье разберём, как настроить автоматические проверки с помощью Husky и lint-staged pre-commit хуков, чтобы избежать багов и сохранить дисциплину в репозитории.
Почему pre-commit хуки пригодятся в команде
Представьте ситуацию: кто-то пушит код с неотформатированными файлами или с нарушением правил линтинга. Это возвращает коллег к исправлениям, создает лишние ревью и ломает CI-процессы. Pre-commit хуки позволяют блокировать такие коммиты на самом раннем этапе.
Они особенно полезны в больших командах и при работе с монорепозиториями, где единая ошибка может повлиять на множество проектов. Автоматизация проверок снижает рутины и даёт уверенность, что в ветке только тот код, который соответствует правилам.
Коротко о Husky и lint-staged
Husky — это утилита для управления Git-хуками. Она упрощает установку и запуск скриптов в точках жизненного цикла Git, например перед коммитом. Husky сам по себе не выполняет линтинг, он лишь запускает нужные команды.
lint-staged фокусируется на изменённых файлах. Он запускает команды только для тех файлов, которые попадают в staged, что экономит время и не мешает разработчику. Вместе они образуют эффективную связку: Husky запускает lint-staged, а тот — набор правил для отдельных файлов.
Как это работает на практике
Когда вы вызываете git commit, Husky перехватывает действие и запускает скрипт pre-commit. В нём обычно прописан вызов lint-staged. lint-staged берёт список staged-файлов и применяет указанные команды к каждому совпадению по шаблону.
Если одна из команд возвращает ошибку, коммит прерывается. Это означает, что проблемный файл остаётся в staged, разработчик может его исправить и повторить коммит. Такой подход не мешает работе, но гарантирует качество.
Шаги установки и базовая конфигурация
Начнём с минимального набора команд. Для npm-проекта достаточно установить обе утилиты как dev-зависимости и инициализировать Husky. Обычно это выглядит так: установить пакеты, включить husky через npx и добавить pre-commit хук, который вызывает lint-staged.
Далее в package.json добавляется настройка lint-staged с шаблонами и командами. Типичный пример: для JavaScript — запуск eslint с автофиксами и повторное добавление исправленных файлов в staged. Такой сценарий часто покрывает большинство проблем с форматированием и стилем кода.
Пример конфигурации
Ниже приведена простая таблица с примерами сопоставления шаблонов файлов и команд, которые удобно использовать в lint-staged. Она показывает компактный и наглядный способ описания правил для разных типов файлов.
| Шаблон | Команда |
|---|---|
| *.js, *.jsx | eslint —fix && prettier —write && git add |
| *.ts, *.tsx | eslint —fix && git add |
| *.css, *.scss | stylelint —fix && git add |
Пошаговая инструкция с реальными командами
Для npm-проекта порядок действий будет таким: установить husky и lint-staged, активировать husky, добавить pre-commit хук и прописать конфигурацию lint-staged. Это рабочая последовательность, которая не требует сложных манипуляций.
Пример команд, которые можно выполнить в терминале, выглядит аккуратно и предсказуемо: npm install —save-dev husky lint-staged; npx husky install; npm pkg set scripts.prepare=»husky install»; npx husky add .husky/pre-commit «npx lint-staged». После этого настройте lint-staged в package.json или отдельном файле.
Пример записи в package.json
В package.json блок lint-staged обычно выглядит компактно и читаемо. Он описывает, какие команды применять к файлам по шаблонам, и не требует отдельного скрипта для каждого типа файлов.
Пример:
{«lint-staged»: {«*.js»: [«eslint —fix», «git add»]}}
Типичные ошибки при настройке и их решение
Одна частая ошибка — забыть добавить git add после автокоррекции. В результате исправления остаются локально, но не попадают в коммит, и попытка повторного коммита может привести к тому, что те же самые ошибки снова блокируют процесс. Всегда ставьте git add в цепочку команд после инструментов, которые изменяют файлы.
Другая проблема — слишком тяжёлые проверки, которые выполняются для всех файлов и затормаживают работу. Решение — использовать lint-staged именно для staged-файлов и распределять тяжелые интеграционные проверки в CI. Это сохраняет скорость локальной работы и не снижает качество в CI.
Что ещё может пойти не так
Иногда команды в lint-staged не находят бинарник, если он установлен локально и путь к нему не указан. В таких случаях полное указание пути через npx или использование скриптов из package.json решает проблему. Ещё одна причина — несовместимость версий eslint, prettier и плагинов; надо следить за версиями и тестировать настройки на CI.
Если хук не срабатывает вообще, проверьте, активирован ли husky (npx husky install) и существует ли файл .husky/pre-commit с правильными правами на исполнение. Эти мелочи обычно и оказываются источником проблем.
Практические советы по использованию в реальных проектах
Не перегружайте pre-commit хуки. Разделите проверки на локальные и CI. Всё, что быстро выполняется и помогает поддерживать стиль, — логично держать в pre-commit. Комплексные тесты и сборки лучше запускать в CI, чтобы не тормозить разработку.
Используйте разделение обязанностей: Husky следит за тем, чтобы хуки запускались, lint-staged выполняет операции только над изменёнными файлами, а сами линтеры и форматтеры делают конкретную работу. Такая композиция предсказуема и масштабируема.
Совместимость с монорепозиториями
В монорепозитории можно разместить общую конфигурацию в корне и иметь локальные переопределения в отдельных пакетах. Важно убедиться, что husky и lint-staged доступны в окружении, в котором выполняется git. Часто помогает ссылка на общие скрипты через npm workspace или pnpm.
Если проект большой, содержите список исключений и не запускайте лишние проверки там, где они не нужны. Это уменьшит шум и ускорит процесс коммитов.
Мой опыт: как одна команда перестала терять время
В одном из проектов мы долгое время боролись с неотформатированным кодом и ошибками линтинга в PR. Внедрили Husky и lint-staged, настроили автопочинку и git add после неё. Поначалу были споры и исправления в конфигурации, но после двух недель команда просто забыла про эту проблему.
Результат оказался заметным: меньше правок в ревью, меньше мелких правок в ветке и более чистая история коммитов. Это не магия, но дисциплина, подкреплённая автоматикой, работает лучше любых напоминаний.
Краткие рекомендации для запуска прямо сейчас
Если хотите быстро попробовать, начните с минимальной конфигурации: eslint —fix для .js и .ts файлов и prettier для форматирования. Добавьте git add, чтобы исправления попадали в коммит, и убедитесь, что husky установлен и активирован.
Постепенно расширяйте правила, добавляйте проверки для стилей, тестов или безопасности, но делайте это итеративно, чтобы команда успевала привыкнуть. Маленькие шаги приносят стабильный эффект.
Husky и lint-staged облегчают рутину, позволяют сосредоточиться на логике, а не на форматировании, и при правильной настройке не мешают разработке. Попробуйте связку на небольшом проекте, доведите конфигурацию до удобного состояния и затем внедрите в основной репозиторий — это экономия времени и нервов в долгосрочной перспективе.

