Настройка Husky для Git-хуков веб-проекта
Husky позволяет запускать скрипты при git-событиях: перед коммитом, перед пушем, при написании сообщения коммита. Практическое применение: автоматический запуск линтера перед каждым коммитом исключает попадание «сломанного» кода в историю.
Установка
npm install --save-dev husky
npx husky init
После init создаётся директория .husky/ с базовым хуком pre-commit и добавляется скрипт "prepare": "husky" в package.json. Скрипт prepare запускается автоматически при npm install — новые члены команды получают хуки без дополнительных шагов.
pre-commit хук
.husky/pre-commit:
npx lint-staged
Запускает lint-staged — инструмент который применяет команды только к staged-файлам, а не ко всему проекту. Конфигурация lint-staged в отдельном файле.
commit-msg хук
Проверяет формат сообщения коммита. Удобно с Conventional Commits:
npm install --save-dev @commitlint/cli @commitlint/config-conventional
.husky/commit-msg:
npx --no -- commitlint --edit $1
commitlint.config.mjs:
export default {
extends: ['@commitlint/config-conventional'],
rules: {
'type-enum': [
2,
'always',
['feat', 'fix', 'docs', 'style', 'refactor', 'test', 'chore', 'revert', 'perf', 'ci'],
],
'subject-max-length': [2, 'always', 72],
'body-max-line-length': [2, 'always', 100],
},
};
Корректный коммит: feat: add user authentication. Некорректный: added stuff — хук заблокирует.
pre-push хук
Для запуска тестов перед пушем:
.husky/pre-push:
npm run test:ci
npm run typecheck
Тесты перед пушем, а не перед каждым коммитом — компромисс между скоростью и надёжностью. Если тесты медленные, pre-commit с тестами убивает продуктивность.
prepare-commit-msg хук
Автоматически добавляет номер задачи из имени ветки в сообщение коммита:
.husky/prepare-commit-msg:
#!/bin/sh
COMMIT_MSG_FILE=$1
COMMIT_SOURCE=$2
# Извлекаем номер задачи из имени ветки (например, feature/PROJ-123-description)
BRANCH_NAME=$(git symbolic-ref --short HEAD 2>/dev/null)
TICKET=$(echo "$BRANCH_NAME" | grep -oE '[A-Z]+-[0-9]+' | head -1)
# Добавляем только если нет уже и это не merge/rebase
if [ -n "$TICKET" ] && [ "$COMMIT_SOURCE" != "merge" ] && [ "$COMMIT_SOURCE" != "squash" ]; then
CURRENT_MSG=$(cat "$COMMIT_MSG_FILE")
if ! echo "$CURRENT_MSG" | grep -q "$TICKET"; then
echo "[$TICKET] $CURRENT_MSG" > "$COMMIT_MSG_FILE"
fi
fi
Обход хуков в экстренных случаях
git commit --no-verify -m "hotfix: emergency patch"
git push --no-verify
--no-verify пропускает хуки. Это намеренная возможность для экстренных ситуаций, а не обход системы — логируется в git истории.
CI и хуки
В CI-окружении хуки не нужны — там линтинг и тесты запускаются явно. Husky автоматически пропускает установку хуков если переменная CI=true:
# husky не устанавливает хуки при CI=true
HUSKY=0 npm ci # или
CI=true npm install
Сроки
Установка Husky с pre-commit + lint-staged: 30–60 минут. Добавление commitlint и настройка Conventional Commits: ещё 30–60 минут.







