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

Локальная разработка и конфигурация рабочей копии проекта

Цель

Обеспечить единые правила локальной разработки и воспроизводимость окружения, чтобы:

  • код был консистентным и предсказуемым
  • проверки работали одинаково в 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 (приоритет)

  1. pnpm
  2. yarn
  3. 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)

  1. pnpm install (или ваш package manager)
  2. pnpm lint / pnpm format / pnpm typecheck выполняются локально
  3. pre-commit/pre-push хуки включены и запускают проверки
  4. Node.js и package manager совпадают с CI (зафиксированы)
  5. новый пакет добавлен с обоснованием и проверкой размера/лицензии/безопасности