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

Локальная разработка

Цель

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

  • код был консистентным и предсказуемым
  • проверки работали одинаково в IDE и CLI
  • расхождения локально/CI не появлялись из-за инструментов

Инструменты качества кода (lint + format)

MUST

  • В каждом проекте настроены:
    • ESLint (статический анализ)
    • Stylelint (если есть CSS/SCSS/CSS Modules)
    • Prettier (форматирование)
  • Проверка типов через TypeScript (если используется)
  • Инструменты запускаются:
    • из CLI
    • из IDE (через плагины и "fix on save")
    • через git-хуки (pre-commit / pre-push)
    • в CI-пайплайне
  • Код, нарушающий стандарты или форматирование, не допускается

SHOULD

  • Настроить lint-staged для ускорения pre-commit хуков

FORBIDDEN

  • Форматирование только через IDE
  • Запуск линтера или prettier напрямую, без package.json scripts

Пример: 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 ничего нет

TypeScript (если используется)

MUST

  • strict: true

  • noImplicitAny: true

  • noUnusedLocals: true

  • noUnusedParameters: true

  • forceConsistentCasingInFileNames: true

  • isolatedModules: true

Примеры

✅ Хорошо
{
"compilerOptions": {
"strict": true,
"noImplicitAny": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"forceConsistentCasingInFileNames": true,
"isolatedModules": true
}
}

❌ Плохо
{
"compilerOptions": {
"strict": false,
"noImplicitAny": false
}
}

Git hooks (pre-commit / pre-push)

MUST

Хуки — часть репозитория, а не локальные скрипты.

Минимальный набор pre-commit:

  • eslint --max-warnings=0
  • prettier --check
  • stylelint (если есть CSS)
  • type-check (если не вынесен в pre-push)

Pre-push:

  • Типизация
  • Тесты (если предусмотрены проектом)

Все команды запускаются через package manager scripts:

  • pnpm run ...
  • yarn ...
  • npm run ...

SHOULD

  • Lefthook — предпочтительный вариант для средних/крупных проектов
  • Husky — допустимо для малых/средних проектов
  • Можно ускорить запуск только для изменённых файлов через lint-staged

FORBIDDEN

  • Использование кастомных shell-хуков
  • Отключение проверок через env

Пример: 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

# ❌ Плохо
pre-commit:
commands:
lint:
run: ./local-lint.sh

Пример: husky (минимально)

✅ Хорошо
# .husky/pre-commit
pnpm lint:fix
pnpm format:fix

❌ Плохо
# .husky/pre-commit
eslint . --fix # ❌ запуск напрямую, без scripts

Package management

MUST

  • Используется один менеджер, фиксируется в package.json
  • Lock-файл (pnpm-lock.yaml / yarn.lock) включён в репозиторий

SHOULD

  • Предпочтительно pnpm, альтернатива — yarn
  • npm — только если нет возможности использовать pnpm/yarn

FORBIDDEN

  • Разные разработчики используют разные package manager → разные lockfiles

Пример

✅ Хорошо (pnpm)
{
"packageManager": "[email protected]"
}

❌ Плохо
- один разработчик использует pnpm, другой yarn — разные lockfiles и разные зависимости

Фиксация версий (runtime & tools)

MUST

  • Версия Node.js фиксируется в одном из форматов:
    • .mise-version (mise)
    • .tool-versions (asdf)
    • package.json -> engines.node
    • Lock-файл включён в репозиторий.

Примеры

✅`mise.toml`
[tools]
node = "20.11.1"
pnpm = "9.12.0"
✅`.tool-versions``
nodejs 20.11.1
pnpm 9.12.0
✅ package.json engines
{
"engines": {
"node": ">=20.11.0 <21"
}
}
✅ lockfile
- pnpm-lock.yaml должен быть в репозитории

SHOULD

  • Все разработчики используют один и тот же менеджер версий (asdf или mise) для консистентности.
  • В CI и локальной среде должны совпадать версии Node и пакетов.

FORBIDDEN

  • Отсутствие lock-файла в репозитории.
  • Разные версии Node в CI и у разработчика.
  • Использование устаревших инструментов для фиксации версий без контроля.

Типы зависимостей

MUST

  • dependencies — только runtime
  • devDependencies — только инструменты разработки
  • peerDependencies — только при архитектурной необходимости
  • Нельзя иметь конфликтующие или необоснованные peerDependencies

Примеры

✅ Хорошо
{
"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"
}
}

Процедуры контроля (Code Review) для зависимостей

MUST

  • Любая новая зависимость проходит review
  • Обоснование добавления:
    • Новый функционал
    • Инфраструктура / архитектура
    • Безопасность / поддержка / производительность

MAY

  • Допустимо добавлять пакеты для:
    • Централизованного state management
    • Работа с датами / таймзонами

FORBIDDEN

  • "Хочу lodash ради одной функции"
  • "Мне так удобнее, я привык"
  • "Один раз распарсить дату — давайте moment"

Стандартный набор dev пакетов проекта

MUST

  • ESLint / TypeScript:
    • 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, lint-staged
  • Commit conventions:
    • commitlint + @commitlint/config-conventional
    • cz-cli / Commitizen
  • Stylelint (если CSS/SCSS)

SHOULD

  • Можно добавить husky / lefthook

IDE Integration

MUST

  • Включить форматирование на сохранение и автофикс:
    • Prettier: “Format on Save”
    • ESLint: “Fix on Save”
    • Stylelint: “Fix on Save” (если доступно)

FORBIDDEN

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. Новый пакет добавлен с обоснованием и проверкой размера / лицензии / безопасности
  6. Нет конфликтов peerDependencies
  7. Все dev-инструменты интегрированы в IDE, git hooks и CI