Контроль качества кода на уровне локального репозитория строится
вокруг Git-хуков, которые запускаются в момент выполнения операций
commit, push и других событий жизненного цикла
репозитория. Pre-commit хуки формируют слой автоматической валидации,
который предотвращает попадание некорректного кода в историю проекта до
запуска CI.
В проектах на Vite этот подход особенно эффективен из-за высокой скорости сборки и ориентации на современный стек ESM, где типичные проверки (lint, форматирование, базовые тесты) выполняются быстро и могут быть встроены в локальный workflow без заметной задержки.
Git hooks представляют собой скрипты, которые автоматически выполняются при наступлении определённых событий:
pre-commit — перед созданием коммитаcommit-msg — проверка сообщения коммитаpre-push — перед отправкой в удалённый репозиторийНа уровне архитектуры это позволяет внедрять слой проверки, не зависящий от CI/CD, и обеспечивать единообразие кода на раннем этапе.
Однако базовый механизм Git неудобен для масштабируемого использования:
Эти ограничения решаются использованием специализированных инструментов.
Husky предоставляет инфраструктуру для декларативного управления Git-хуками внутри проекта. Основная цель — сделать хуки частью репозитория и упростить их распространение между разработчиками.
В проектах на Vite Husky обычно устанавливается как dev-зависимость:
npm install -D husky
Инициализация структуры хуков:
npx husky init
После выполнения создаётся директория .husky/, которая
становится точкой управления всеми Git hooks проекта.
Структура типичного Vite-проекта после добавления Husky:
project/
├─ src/
├─ public/
├─ vite.config.js
├─ package.json
├─ .husky/
│ ├─ pre-commit
│ ├─ commit-msg
Husky подключается к Git hooks через внутренние shell-скрипты. Каждый
файл в .husky/ соответствует определённому событию Git.
Пример pre-commit:
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npm test
При каждом коммите выполняется указанный набор команд.
В Vite-проектах логика обычно делегируется
package.json:
{
"scripts": {
"lint": "eslint .",
"format": "prettier --write .",
"test": "vitest"
}
}
Husky вызывает уже готовые npm-скрипты, что упрощает поддержку и снижает дублирование логики.
lint-staged решает ключевую проблему pre-commit хуков — избыточное выполнение линтеров по всему проекту.
Вместо анализа всей кодовой базы выполняется обработка только файлов, добавленных в staging area Git.
lint-staged получает список staged файлов и фильтрует их по шаблонам, после чего выполняет заданные команды.
Это обеспечивает:
Установка:
npm install -D lint-staged
Добавление конфигурации в package.json:
{
"lint-staged": {
"*.{js,ts,vue}": [
"eslint --fix",
"prettier --write"
],
"*.{json,md}": [
"prettier --write"
]
}
}
Каждый паттерн соответствует набору файлов, к которым применяются операции.
На практике эти инструменты работают совместно:
Пример .husky/pre-commit:
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx lint-staged
В результате commit становится точкой автоматической валидации изменений.
Vite ориентирован на модульную архитектуру и быстрый dev server, поэтому pre-commit проверки не должны конфликтовать с его скоростью разработки.
Типичный стек:
ESLint конфигурация для современного ESM-проекта:
export default [
{
files: ["src/**/*.{js,ts,vue}"],
rules: {
"no-console": "warn",
"no-unused-vars": "error"
}
}
];
Lint-staged вызывает ESLint только на изменённых файлах, снижая время проверки до долей секунды.
Форматирование кода в pre-commit этапе устраняет конфликты стиля между разработчиками.
Пример интеграции:
{
"lint-staged": {
"*.{js,ts,vue}": [
"prettier --write"
]
}
}
Prettier выполняется до ESLint или после него в зависимости от стратегии:
В Vite-экосистеме часто используется Vitest как тестовый раннер.
Пример добавления в lint-staged:
{
"lint-staged": {
"*.{js,ts}": [
"vitest related --run"
]
}
}
Однако запуск тестов в pre-commit требует баланса:
Husky позволяет подключить проверку формата коммитов.
Пример установки commitlint:
npm install -D @commitlint/config-conventional @commitlint/cli
Конфигурация:
export default {
extends: ["@commitlint/config-conventional"]
};
Husky hook:
npx husky add .husky/commit-msg "npx --no -- commitlint --edit $1"
Это обеспечивает стандартизацию истории Git.
Основной риск pre-commit хуков — замедление процесса коммита.
Факторы оптимизации:
Пример оптимизированной конфигурации:
{
"lint-staged": {
"*.{js,ts,vue}": [
"eslint --cache --fix",
"prettier --write"
]
}
}
Ключевой параметр --cache значительно сокращает время
повторных проверок.
В монорепозиториях (Turborepo, Nx) pre-commit hooks требуют дополнительной координации.
Особенности:
Пример:
{
"lint-staged": {
"packages/*/src/**/*.{js,ts}": [
"eslint --fix"
]
}
}
Причины:
.husky/ директория в репозиторииПричины:
Возможные проблемы:
Решение обычно связано с настройкой Git:
git config --global core.autocrlf true
В современной фронтенд-архитектуре pre-commit слой выполняет функцию локального gatekeeper-а, снижая нагрузку на CI и уменьшая количество дефектов, попадающих в удалённый репозиторий.
Комбинация Vite + Husky + lint-staged формирует лёгкую, но эффективную систему контроля качества, где: