Перейти к содержимому

Как внедрить Husky в рабочий проект: от установки до production-ready хуков

Константин Потапов
18 мин

Пошаговое руководство по внедрению Husky и автоматизации качества кода через git-хуки. С готовыми конфигами для JavaScript/TypeScript и Python проектов.

Как внедрить Husky в рабочий проект: от установки до production-ready хуков

Проблема: код ломается после коммита

Сколько раз это случалось с вами: пушите код в репозиторий, CI падает с ошибкой линтера или тестов, которую вы могли поймать локально за 5 секунд. Коллеги ждут, пайплайн занят, а вы делаете ещё один коммит с фиксом.

Или классика: кто-то в команде коммитит код с console.log(), неиспользуемыми импортами или с форматированием "как получилось". Code review превращается в обсуждение отступов вместо архитектуры.

Цена проблемы:

  • 10-15 минут на каждый сломанный CI-пайплайн
  • Загрязнённая история коммитов
  • Потеря времени ревьюеров на обсуждение форматирования
  • Риск попадания сломанного кода в production

Решение: автоматизировать проверки до коммита с помощью git-хуков и Husky.

Git-хуки — это скрипты, которые автоматически запускаются на определённых этапах работы с Git (перед коммитом, перед пушем, после чекаута и т.д.). Husky — это инструмент, который упрощает настройку и управление этими хуками в современных JavaScript-проектах.

Что такое Husky и зачем он нужен

Husky — это популярный npm-пакет для управления git-хуками в JavaScript-проектах. Он позволяет:

  • Запускать проверки автоматически перед коммитом или пушем
  • Форматировать код перед коммитом (через Prettier или ESLint --fix)
  • Запускать тесты перед пушем в удалённый репозиторий
  • Валидировать commit-сообщения (через commitlint)
  • Гарантировать качество кода на уровне локальной машины разработчика

Ключевое преимущество: проблемы находятся до того, как попадут в репозиторий, а не после.

0 мин
Время на фикс сломанного CI
100%
Код проходит проверки до коммита
-80%
Споров о форматировании на ревью
5-10 сек
Время проверки перед коммитом

С чем работает Husky

Husky отлично интегрируется с популярными инструментами:

ESLintPrettierTypeScriptJestVitestcommitlintlint-staged

Типичная связка:

  • Husky — управляет git-хуками
  • lint-staged — запускает проверки только на изменённых файлах (а не на всём проекте)
  • ESLint — проверяет качество кода
  • Prettier — форматирует код
  • commitlint — проверяет формат commit-сообщений

Установка и базовая настройка

Шаг 1: Установка Husky

# Установка Husky (используйте версию 9+)
npm install --save-dev husky
 
# Инициализация Husky (создаёт .husky/ директорию)
npx husky init

После выполнения команды npx husky init у вас появится:

  • Директория .husky/ с примером хука pre-commit
  • Скрипт "prepare": "husky" в package.json

Что делает prepare-скрипт:

Этот скрипт автоматически запускается при npm install и настраивает Husky для каждого разработчика, который клонирует репозиторий. Это гарантирует, что git-хуки будут работать у всех в команде без дополнительных действий.

Шаг 2: Установка lint-staged

lint-staged — это инструмент, который запускает проверки только на файлах, которые вы добавили в staging area. Это критически важно для производительности: вместо проверки 1000 файлов вы проверяете только 5 изменённых.

npm install --save-dev lint-staged

Создайте конфигурационный файл lint-staged.config.js в корне проекта:

module.exports = {
  // Для JavaScript/TypeScript файлов
  "*.{js,jsx,ts,tsx}": [
    "eslint --fix", // Автофикс проблем ESLint
    "prettier --write", // Форматирование через Prettier
  ],
 
  // Для стилей
  "*.{css,scss,less}": ["prettier --write"],
 
  // Для JSON, Markdown и других файлов
  "*.{json,md,mdx,yml,yaml}": ["prettier --write"],
};

Важно: используйте lint-staged.config.js вместо встроенной конфигурации в package.json, если у вас сложная логика или нужны комментарии.

Шаг 3: Настройка pre-commit хука

Теперь настроим хук, который будет запускаться перед каждым коммитом.

Откройте файл .husky/pre-commit (он был создан при инициализации) и замените его содержимое:

# .husky/pre-commit
npx lint-staged

Вот и всё! Теперь перед каждым коммитом будет запускаться lint-staged, который проверит только изменённые файлы.

Шаг 4: Тестирование

Проверим, что хуки работают:

# Создайте файл с ошибкой ESLint
echo "const unused = 'variable'" > test.js
 
# Добавьте в staging
git add test.js
 
# Попробуйте закоммитить
git commit -m "test commit"

Если всё настроено правильно, вы увидите:

✔ Preparing lint-staged...
✔ Running tasks for staged files...
✔ Applying modifications from tasks...
✔ Cleaning up temporary files...

Если ESLint нашёл ошибки, коммит будет заблокирован:

✖ eslint --fix:
  error  'unused' is assigned a value but never used  no-unused-vars

✖ lint-staged failed

Продвинутая настройка: production-ready конфигурация

Теперь настроим Husky для реального проекта с TypeScript, тестами и валидацией коммитов.

Конфигурация lint-staged с TypeScript

Для TypeScript-проектов важно не только проверять линтером, но и запускать type-checking:

// lint-staged.config.js
module.exports = {
  // TypeScript/JavaScript файлы
  "*.{ts,tsx,js,jsx}": [
    "eslint --fix --max-warnings=0", // Блокируем коммит, если есть warnings
    "prettier --write",
  ],
 
  // Проверка типов TypeScript (только один раз на все файлы)
  "*.{ts,tsx}": () => "tsc --noEmit",
 
  // Стили
  "*.{css,scss,module.css}": ["prettier --write"],
 
  // Markdown и документация
  "*.{md,mdx}": ["prettier --write"],
 
  // Конфиги
  "*.{json,yml,yaml}": ["prettier --write"],
};

Обратите внимание: для TypeScript type-checking используется синтаксис () => "команда", потому что tsc проверяет весь проект целиком, а не отдельные файлы. Это важно для корректной работы системы типов.

Добавление pre-push хука для тестов

Запускать все тесты перед каждым коммитом — слишком медленно. Лучше запускать их перед пушем:

# Создаём pre-push хук
npx husky add .husky/pre-push "npm test"

Или если вы используете конкретный тестовый раннер:

# .husky/pre-push
npm run test:ci  # Запускает тесты без watch-режима

Валидация commit-сообщений с commitlint

Установим commitlint для проверки формата коммитов (например, Conventional Commits):

# Установка commitlint
npm install --save-dev @commitlint/cli @commitlint/config-conventional
 
# Создание конфига
echo "module.exports = { extends: ['@commitlint/config-conventional'] };" > commitlint.config.js
 
# Добавление хука
npx husky add .husky/commit-msg 'npx --no -- commitlint --edit $1'

Теперь коммиты должны соответствовать формату:

feat: добавлена новая фича
fix: исправлен баг в модуле авторизации
docs: обновлена документация
chore: обновлены зависимости

Попытка закоммитить с неправильным форматом будет заблокирована:

git commit -m "добавил фичу"
# ⧗   input: добавил фичу
# ✖   subject may not be empty [subject-empty]
# ✖   type may not be empty [type-empty]

Реальный кейс: настройка для Next.js проекта

Вот полная конфигурация из production-проекта на Next.js 15 с TypeScript:

// lint-staged.config.js
module.exports = {
  // TypeScript и JavaScript
  "*.{ts,tsx,js,jsx}": ["eslint --fix --max-warnings=0", "prettier --write"],
 
  // Type-checking для TypeScript (на весь проект)
  "*.{ts,tsx}": () => "tsc --noEmit",
 
  // Стили и CSS Modules
  "*.{css,scss}": ["prettier --write"],
 
  // MDX контент (блог, документация)
  "*.{md,mdx}": ["prettier --write"],
 
  // JSON конфиги
  "*.json": ["prettier --write"],
};
# .husky/pre-commit
npx lint-staged
# .husky/pre-push
npm run build      # Проверяем, что билд не сломан
npm run test:ci    # Запускаем тесты
// commitlint.config.js
module.exports = {
  extends: ["@commitlint/config-conventional"],
  rules: {
    "type-enum": [
      2,
      "always",
      [
        "feat", // Новая фича
        "fix", // Багфикс
        "docs", // Документация
        "style", // Форматирование (не влияет на код)
        "refactor", // Рефакторинг
        "test", // Тесты
        "chore", // Обновление зависимостей, конфигов
        "perf", // Улучшение производительности
        "ci", // CI/CD
        "build", // Система сборки
        "revert", // Откат коммита
      ],
    ],
    "subject-case": [0], // Отключаем проверку регистра для русских коммитов
  },
};

Результат: весь код, который попадает в репозиторий, автоматически проходит проверки на качество, форматирование и типы. Вероятность сломанного CI — почти нулевая.

Husky для Python-проектов

Husky — это не только для JavaScript! Git-хуки работают с любым языком программирования. Давайте настроим Husky для Python-проекта с современными инструментами проверки качества кода.

Важно: Хотя Husky — это npm-пакет, он отлично работает с Python-проектами. Вам нужен только Node.js для установки самого Husky, но хуки будут запускать Python-инструменты.

Инструменты для Python

RuffBlackmypypytestisort

Современный стек для Python-проектов:

  • Ruff — сверхбыстрый линтер и форматер (замена Flake8, isort, и частично Black)
  • Black — непримиримый форматировщик кода
  • mypy — проверка типов (type checking)
  • pytest — тестирование
  • isort — сортировка импортов (если не используете Ruff)

Базовая настройка для Python

Шаг 1: Установка Husky

# Инициализируем npm проект (если его ещё нет)
npm init -y
 
# Устанавливаем Husky
npm install --save-dev husky lint-staged
npx husky init

Шаг 2: Установка Python-инструментов

# Через pip
pip install ruff black mypy pytest
 
# Или через poetry
poetry add --group dev ruff black mypy pytest
 
# Или через requirements-dev.txt
echo "ruff>=0.1.0" >> requirements-dev.txt
echo "black>=23.0.0" >> requirements-dev.txt
echo "mypy>=1.7.0" >> requirements-dev.txt
echo "pytest>=7.4.0" >> requirements-dev.txt
pip install -r requirements-dev.txt

Шаг 3: Настройка lint-staged для Python

Создайте lint-staged.config.js:

module.exports = {
  // Python файлы: проверка Ruff и форматирование Black
  "*.py": [
    "ruff check --fix", // Проверка и автофикс через Ruff
    "black", // Форматирование через Black
    "mypy --ignore-missing-imports", // Type checking
  ],
 
  // Jupyter notebooks (если используете)
  "*.ipynb": ["ruff check --fix"],
 
  // YAML конфиги
  "*.{yml,yaml}": [
    "yamllint", // Линтер для YAML
  ],
 
  // Markdown документация
  "*.md": [],
};

Шаг 4: Настройка pre-commit хука

# .husky/pre-commit
npx lint-staged

Шаг 5: Настройка pre-push хука для тестов

# .husky/pre-push
pytest tests/                    # Запуск всех тестов

Вариант 1: Только Ruff (самый быстрый)

Ruff — это современный "всё-в-одном" инструмент для Python. Он заменяет Flake8, isort, pyupgrade и частично Black.

// lint-staged.config.js
module.exports = {
  "*.py": [
    "ruff check --fix --select I", // Проверка и сортировка импортов
    "ruff check --fix", // Проверка и автофикс всех правил
    "ruff format", // Форматирование (альтернатива Black)
  ],
};

Конфигурация Ruff (pyproject.toml):

[tool.ruff]
# Максимальная длина строки
line-length = 88
 
# Python версия
target-version = "py311"
 
# Файлы для игнорирования
exclude = [
    ".git",
    ".venv",
    "__pycache__",
    "build",
    "dist",
]
 
[tool.ruff.lint]
# Правила для проверки (эквивалент Flake8, pycodestyle, isort и др.)
select = [
    "E",   # pycodestyle errors
    "W",   # pycodestyle warnings
    "F",   # pyflakes
    "I",   # isort
    "N",   # pep8-naming
    "UP",  # pyupgrade
    "B",   # flake8-bugbear
    "C4",  # flake8-comprehensions
    "DTZ", # flake8-datetimez
    "T10", # flake8-debugger
    "SIM", # flake8-simplify
]
 
# Игнорируемые правила
ignore = [
    "E501",  # line-too-long (Black справляется)
]
 
# Автофикс для правил
fixable = ["ALL"]
unfixable = []
 
[tool.ruff.format]
# Использовать двойные кавычки
quote-style = "double"
 
# Отступы
indent-style = "space"
 
# Совместимость с Black
skip-magic-trailing-comma = false
line-ending = "auto"

Преимущество Ruff: скорость! Ruff в 10-100 раз быстрее Flake8/Pylint и работает за миллисекунды даже на больших проектах.

Вариант 2: Ruff + Black + mypy (классический стек)

Если вы хотите использовать Black для форматирования и mypy для type-checking:

// lint-staged.config.js
module.exports = {
  "*.py": [
    "ruff check --fix --select I", // Сортировка импортов через Ruff
    "black --check", // Проверка форматирования
    "black", // Применение форматирования
    "ruff check --fix", // Линтинг через Ruff
    "mypy", // Type checking
  ],
};

Конфигурация Black (pyproject.toml):

[tool.black]
line-length = 88
target-version = ['py311']
include = '\.pyi?$'
exclude = '''
/(
    \.git
  | \.venv
  | build
  | dist
)/
'''

Конфигурация mypy (pyproject.toml):

[tool.mypy]
python_version = "3.11"
warn_return_any = true
warn_unused_configs = true
disallow_untyped_defs = true
disallow_incomplete_defs = true
check_untyped_defs = true
no_implicit_optional = true
 
# Игнорировать отсутствующие типы в библиотеках
ignore_missing_imports = true
 
# Строгий режим (опционально)
# strict = true

Вариант 3: Pylint вместо Ruff (для строгих проверок)

Pylint — более строгий и детальный линтер, но медленнее Ruff.

// lint-staged.config.js
module.exports = {
  "*.py": [
    "black", // Форматирование
    "isort", // Сортировка импортов
    "pylint --errors-only", // Только ошибки (быстрее)
    // "pylint",                     // Полная проверка (медленно)
    "mypy", // Type checking
  ],
};

Конфигурация Pylint (.pylintrc):

[MASTER]
# Игнорируемые файлы
ignore=CVS,.git,__pycache__,.venv
 
# Количество процессов (0 = автоопределение)
jobs=0
 
[MESSAGES CONTROL]
# Отключённые правила
disable=
    C0111,  # missing-docstring
    C0103,  # invalid-name
    R0903,  # too-few-public-methods
    W0212,  # protected-access
 
[FORMAT]
# Максимальная длина строки
max-line-length=88
 
# Отступы
indent-string='    '
 
[DESIGN]
# Максимум аргументов функции
max-args=7
 
# Максимум атрибутов класса
max-attributes=10

Внимание: Pylint медленнее Ruff в 50-100 раз. На больших проектах это может замедлить коммиты до 10-30 секунд. Рекомендуется использовать --errors-only или переносить в pre-push.

Оптимизация: быстрые проверки в pre-commit, медленные в pre-push

Для больших Python-проектов рекомендуется разделить проверки:

Быстрые проверки (pre-commit):

// lint-staged.config.js
module.exports = {
  "*.py": [
    "ruff check --fix --select I", // Импорты
    "ruff format", // Форматирование
    "ruff check --fix", // Быстрые проверки
  ],
};

Медленные проверки (pre-push):

# .husky/pre-push
#!/bin/sh
 
# Type checking на весь проект
echo "Running mypy type checking..."
mypy src/
 
# Полные тесты
echo "Running pytest..."
pytest tests/ -v
 
# Проверка покрытия тестами (опционально)
# pytest tests/ --cov=src --cov-report=term-missing --cov-fail-under=80

Реальный кейс: FastAPI проект с Poetry

Полная конфигурация для production FastAPI-проекта:

# pyproject.toml
[tool.poetry]
name = "my-fastapi-app"
version = "0.1.0"
description = ""
authors = ["Your Name <you@example.com>"]
 
[tool.poetry.dependencies]
python = "^3.11"
fastapi = "^0.104.0"
uvicorn = "^0.24.0"
pydantic = "^2.5.0"
sqlalchemy = "^2.0.0"
 
[tool.poetry.group.dev.dependencies]
ruff = "^0.1.0"
black = "^23.11.0"
mypy = "^1.7.0"
pytest = "^7.4.0"
pytest-cov = "^4.1.0"
pytest-asyncio = "^0.21.0"
httpx = "^0.25.0"
 
# Конфигурация Ruff
[tool.ruff]
line-length = 88
target-version = "py311"
exclude = [".venv", "migrations"]
 
[tool.ruff.lint]
select = ["E", "W", "F", "I", "N", "UP", "B", "C4", "SIM"]
ignore = ["E501"]
fixable = ["ALL"]
 
# Конфигурация Black
[tool.black]
line-length = 88
target-version = ['py311']
exclude = '''/(\.venv|migrations)/'''
 
# Конфигурация mypy
[tool.mypy]
python_version = "3.11"
warn_return_any = true
warn_unused_configs = true
disallow_untyped_defs = true
plugins = ["pydantic.mypy"]
 
[[tool.mypy.overrides]]
module = "sqlalchemy.*"
ignore_missing_imports = true
 
# Конфигурация pytest
[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = "test_*.py"
python_functions = "test_*"
asyncio_mode = "auto"
// lint-staged.config.js
module.exports = {
  "*.py": [
    "ruff check --fix --select I",
    "ruff format",
    "ruff check --fix",
    "mypy",
  ],
  "*.{json,yml,yaml}": [],
};
# .husky/pre-commit
npx lint-staged
# .husky/pre-push
#!/bin/sh
 
echo "🔍 Running type checking..."
poetry run mypy src/
 
echo "🧪 Running tests..."
poetry run pytest tests/ -v --cov=src --cov-report=term-missing
 
echo "✅ All checks passed!"
// package.json
{
  "name": "my-fastapi-app",
  "private": true,
  "scripts": {
    "prepare": "husky"
  },
  "devDependencies": {
    "husky": "^9.0.0",
    "lint-staged": "^15.0.0"
  }
}

Django проект: особенности настройки

Для Django-проектов добавьте проверку миграций:

// lint-staged.config.js
module.exports = {
  "*.py": [
    "ruff check --fix --select I",
    "ruff format",
    "ruff check --fix",
    "mypy --ignore-missing-imports",
  ],
 
  // Проверка миграций при изменении моделей
  "**/models.py": () => "python manage.py makemigrations --check --dry-run",
};
# .husky/pre-push
#!/bin/sh
 
echo "🔍 Checking migrations..."
python manage.py makemigrations --check --dry-run
 
echo "🧪 Running tests..."
python manage.py test
 
echo "🔐 Running security checks..."
python manage.py check --deploy
 
echo "✅ All checks passed!"

Сравнение инструментов для Python

Традиционный стек
Современный стек
Инструмент
Pylint
Ruff
Скорость проверки (1000 файлов)
~45 секунд
~0.5 секунды
99%
Строгость проверок
Очень высокая
Высокая
Автофикс
Нет
Да

Рекомендации:

  • Для новых проектов: Ruff + mypy (быстро, современно, достаточно строго)
  • Для legacy-проектов: Постепенная миграция с Pylint на Ruff
  • Для строгих корпоративных стандартов: Ruff + Pylint (только ошибки) + mypy

Чек-лист для Python-проектов

  • Установлен Husky и lint-staged
  • Установлены Python-инструменты (Ruff/Black/mypy)
  • Создан pyproject.toml с конфигурацией
  • Настроен lint-staged.config.js для Python-файлов
  • Настроен .husky/pre-commit для быстрых проверок
  • Настроен .husky/pre-push для тестов
  • Добавлен .gitignore для Python (.venv, __pycache__, и т.д.)
  • Протестировано: коммит с ошибкой блокируется
  • Протестировано: коммит с валидным кодом проходит

Проблемы и решения

Проблема 1: Хуки не работают после клонирования

Симптом: коллега клонировал репозиторий, но git-хуки не запускаются.

Причина: не выполнился prepare скрипт при npm install.

Решение:

Убедитесь, что в package.json есть:

{
  "scripts": {
    "prepare": "husky"
  }
}

Попросите коллег выполнить после клонирования:

npm install  # Это запустит prepare автоматически

Проблема 2: Хуки слишком медленные

Симптом: коммит занимает 30+ секунд.

Причина: проверки запускаются на всех файлах проекта, а не только на изменённых.

Решение:

  1. Используйте lint-staged — он проверяет только staged-файлы
  2. Не запускайте тесты в pre-commit, перенесите их в pre-push
  3. Используйте кеширование в ESLint:
// lint-staged.config.js
module.exports = {
  "*.{ts,tsx,js,jsx}": [
    "eslint --cache --fix", // Добавляем --cache
    "prettier --write",
  ],
};

Проблема 3: Нужно обойти хуки в экстренном случае

Симптом: нужно срочно закоммитить, но хуки блокируют.

Решение (используйте с осторожностью!):

# Пропустить pre-commit и commit-msg хуки
git commit --no-verify -m "emergency fix"
 
# Пропустить pre-push хук
git push --no-verify

Не злоупотребляйте --no-verify! Используйте только в экстренных случаях (hotfix на production). В остальных случаях — исправьте ошибки, которые нашёл линтер.

Проблема 4: ESLint ругается на файлы, которые не должны проверяться

Причина: lint-staged передаёт в ESLint файлы, которые нужно игнорировать.

Решение:

Создайте/обновите .eslintignore:

# .eslintignore
node_modules/
.next/
out/
dist/
build/
*.config.js

Или настройте lint-staged явно:

module.exports = {
  "*.{ts,tsx,js,jsx}": (filenames) => {
    const filteredFiles = filenames
      .filter((file) => !file.includes("node_modules"))
      .filter((file) => !file.includes(".next"));
 
    return `eslint --fix ${filteredFiles.join(" ")}`;
  },
};

Внедрение в существующий проект (миграция)

Если у вас уже есть большой проект с существующим кодом, который не проходит проверки:

Стратегия 1: Постепенное внедрение

  1. Установите Husky и lint-staged
  2. Настройте только Prettier (автофикс не ломает код):
// lint-staged.config.js
module.exports = {
  "*.{ts,tsx,js,jsx}": ["prettier --write"],
};
  1. Через неделю добавьте ESLint с --fix:
module.exports = {
  "*.{ts,tsx,js,jsx}": ["eslint --fix", "prettier --write"],
};
  1. Через месяц добавьте type-checking и тесты

Стратегия 2: Проверка только новых файлов

Используйте --max-warnings для постепенного улучшения:

module.exports = {
  "*.{ts,tsx,js,jsx}": [
    "eslint --fix --max-warnings=10", // Позволяем 10 warnings, постепенно снижаем
    "prettier --write",
  ],
};

Каждый спринт снижайте лимит: 10 → 5 → 0.

Стратегия 3: Игнорирование legacy-кода

Добавьте legacy-файлы в .eslintignore:

# Legacy код, который рефакторим постепенно
src/legacy/
src/old-api/

Новый код проверяется строго, старый — постепенно рефакторится.

Скрипты для package.json

Полезные команды для работы с git-хуками:

{
  "scripts": {
    "prepare": "husky",
    "lint": "eslint . --ext .ts,.tsx,.js,.jsx",
    "lint:fix": "eslint . --ext .ts,.tsx,.js,.jsx --fix",
    "format": "prettier --write \"**/*.{ts,tsx,js,jsx,css,md,json}\"",
    "format:check": "prettier --check \"**/*.{ts,tsx,js,jsx,css,md,json}\"",
    "type-check": "tsc --noEmit",
    "test:ci": "vitest run",
    "validate": "npm run lint && npm run type-check && npm run test:ci"
  }
}

Команда validate полезна для проверки проекта целиком (например, перед созданием PR):

npm run validate

Метрики успеха внедрения

Через месяц после внедрения Husky вы должны увидеть:

До Husky
После Husky
Сломанных CI-пайплайнов
5-10 в неделю
0-1 в месяц
100%
Времени на фикс CI
15-20 мин
0 мин
100%
Споров о форматировании
Каждое ревью
Нет
Ошибок в production
2-3 в месяц
0-1 в месяц
100%

Дополнительные метрики:

  • Время code review сокращается на 30-40% (не нужно обсуждать форматирование)
  • Качество кода растёт (автоматические проверки находят проблемы рано)
  • Меньше стресса у команды (CI почти не падает)

Чек-лист для внедрения

Используйте этот чек-лист для внедрения Husky в ваш проект:

  • Установлен Husky (npm install --save-dev husky)
  • Выполнена инициализация (npx husky init)
  • Установлен lint-staged (npm install --save-dev lint-staged)
  • Создан lint-staged.config.js с проверками
  • Настроен .husky/pre-commit для запуска lint-staged
  • (Опционально) Настроен .husky/pre-push для тестов/билда
  • (Опционально) Установлен commitlint для валидации коммитов
  • Добавлен prepare скрипт в package.json
  • Протестировано: коммит с ошибкой ESLint блокируется
  • Протестировано: коммит с валидным кодом проходит
  • Команда проинформирована о новых правилах
  • Документация обновлена (README или CONTRIBUTING.md)

Вывод

Husky и git-хуки — это не просто "удобная автоматизация". Это смена культуры разработки в команде.

Что вы получаете:

  • Код всегда проходит минимальные проверки качества до попадания в репозиторий
  • CI/CD пайплайны перестают падать из-за тривиальных ошибок
  • Code review фокусируется на архитектуре и логике, а не на форматировании
  • Новые разработчики сразу получают автоматические проверки после npm install

Время на внедрение:

  • Базовая настройка: 15-30 минут
  • Production-ready конфигурация: 1-2 часа
  • Окупаемость: уже через неделю (экономия времени на исправлении CI)

Следующий шаг:

Откройте терминал прямо сейчас и выполните:

npm install --save-dev husky lint-staged
npx husky init

Создайте lint-staged.config.js из примеров выше — и ваш проект уже защищён от тривиальных ошибок.

Автоматизация качества — это не про контроль, а про то, чтобы разработчики фокусировались на важном, а рутинные проверки выполнялись сами.