Локальная разработка и конфигурация рабочей копии проекта
Цель
Обеспечить единые правила локальной разработки и воспроизводимость окружения, чтобы:
- код был консистентным и предсказуемым
- проверки работали одинаково в IDE и CLI
- расхождения локально/CI не появлялись из-за инструментов
Инструменты качества кода (lint + format)
MUST
- В каждом проекте настроены:
- ESLint (статический анализ)
- Stylelint (если есть CSS/SCSS/CSS Modules)
- Prettier (форматирование)
- Инструменты должны запускаться:
- из CLI
- из IDE (через плагины и "fix on save")
Пример: package.json scripts (эталон)
✅ Хорошо
{
"scripts": {
"deps:check": "depcruise --config ./.dependency-cruiser.js --no-ignore-known",
"fsd:deps:check": "node node_modules/fsd-cruise/bin.js",
"lint:eslint": "eslint",
"lint:eslint:fix": "eslint --fix",
"lint:eslint:project": "eslint --quiet .",
"lint:eslint:project:fix": "eslint . --fix",
"lint:prettier": "prettier --check '**/*.{ts,tsx}'",
"lint:prettier:fix": "prettier --write '**/*.{ts,tsx}'",
"lint:stylelint": "stylelint '**/*.{css,scss}'",
"lint:stylelint:fix": "stylelint '**/*.{css,scss}' --fix",
"lint:typescript": "tsc --noEmit -p tsconfig.json",
"lint:typescript:fix": "tsc --noEmit -p tsconfig.json --fix",
"lint:ci": "pnpm lint:typescript && pnpm lint:eslint:project"
}
}
❌ Плохо
- нет lint/format/typecheck скриптов
- форматирование только через IDE, а в CLI ничего нет
Git hooks (pre-commit / pre-push)
MUST
- Перед попаданием кода в репозиторий должны выполняться проверки.
- Хуки - часть репозитория, а не "локальные магические скрипты".
Инструменты
- lefthook — предпочтительно для средних/крупных проектов
- husky — допустимо для небольших проектов
Пример: lefthook.yml (pre-commit + pre-push)
# ✅ Хорошо
pre-commit:
parallel: true
commands:
format:
run: pnpm format:fix
lint:
run: pnpm lint:fix
stylelint:
run: pnpm stylelint:fix
pre-push:
commands:
typecheck:
run: pnpm typecheck
test:
run: pnpm test
Плюс: можно ускорить, запуская только изменённые файлы через lint-staged (если используете).
❌ Плохо
- hooks запускают неизвестные локальные .sh файлы, которых нет в репозитории
- hooks выключают проверки через env
Пример: husky (минимально)
✅ Хорошо
# .husky/pre-commit
pnpm lint:fix
pnpm format:fix
❌ Плохо
# .husky/pre-commit
eslint . --fix # ❌ запуск напрямую, без scripts
Все команды должны идти через pnpm run ... / npm run ... / yarn ... и быть описаны в package.json.
Package management
SHOULD (приоритет)
- pnpm
- yarn
- npm (если нет возможности использовать pnpm/yarn)
MUST
- В проекте используется один package manager.
- Он фиксируется в package.json полем packageManager.
✅ Пример (pnpm)
{
"packageManager": "[email protected]"
}
❌ Плохо
- один разработчик использует pnpm, другой yarn — разные lockfiles и разные зависимости
Фиксация версий (runtime & tools)
MUST
- Версия Node.js фиксируется в одном из форматов:
- .tool-versions (asdf)
- package.json -> engines.node
- Lock-файл включён в репозиторий.
✅ Пример: .tool-versions
nodejs 20.11.1
pnpm 9.12.0
✅ Пример: package.json engines
{
"engines": {
"node": ">=20.11.0 <21"
}
}
✅ Пример: lockfile
- pnpm-lock.yaml должен быть в репозитории
❌ Плохо
- отсутствует lockfile
- в CI Node 20, а у разработчика Node 18 (или наоборот)
Типы зависимостей (dependencies vs devDependencies)
MUST
- dependencies - только то, что нужно приложению в production.
- Dependencies - только инструменты разработки.
✅ Хорошо
{
"dependencies": {
"react": "^18.2.0",
"zustand": "^4.5.0"
},
"devDependencies": {
"typescript": "~5.2.2",
"eslint": "^9.0.0",
"prettier": "^3.2.4"
}
}
❌ Плохо
{
"dependencies": {
"eslint": "^9.0.0",
"prettier": "^3.2.4"
}
}
Peer dependencies
MUST
- Не должно быть неразрешённых peer dependencies.
✅ Хорошо
- после установки зависимостей нет предупреждений peer deps
- CI валидирует установку (например pnpm install --frozen-lockfile)
❌ Плохо
- "warnings" игнорируются месяцами и потом ломают CI/билды
Процедуры контроля (Code Review) для зависимостей
MUST
Любая новая зависимость требует обоснования
- новый функционал
- инфраструктура/архитектура
- безопасность/поддержка/перфоманс
Допустимо (примеры)
- Добавить state manager при переходе к централизованному состоянию
- Добавить date-библиотеку при активной работе с датами/таймзонами
Недопустимо (примеры)
- "Хочу lodash ради одной функции"
- "Мне так удобнее, я привык'
- "Нужно один раз распарсить дату — давайте moment"
Стандартный набор dev пакетов проекта
ESLint / TS
- eslint
- @eslint/js
- typescript-eslint
- eslint-config-prettier
- eslint-import-resolver-typescript
- eslint-plugin-import-x
- eslint-plugin-prettier
- eslint-plugin-react
- eslint-plugin-react-hooks
- prettier
- globals
Commit conventions
- commitlint + @commitlint/config-conventional
- cz-cli / Commitizen
Stylelint
- stylelint (если используете CSS/SCSS)
IDE Integration (пример)
MUST
- Включить форматирование на сохранение и автофикс ESLint:
- Prettier: “Format on Save”
- ESLint: “Fix on Save”
- Stylelint: “Fix on Save” (если доступно)
✅ Хорошо
- разработчик сохраняет файл → применяются prettier + eslint fixes
- при пуше хуки гарантируют те же правила
❌ Плохо
- IDE “форматирует по-своему”, а CLI — по-другому
Мини-чеклист (локально/PR)
- pnpm install (или ваш package manager)
- pnpm lint / pnpm format / pnpm typecheck выполняются локально
- pre-commit/pre-push хуки включены и запускают проверки
- Node.js и package manager совпадают с CI (зафиксированы)
- новый пакет добавлен с обоснованием и проверкой размера/лицензии/безопасности