Monorepo: pnpm workspaces, Nx, Turborepo

↑ 6.2 Сборка и инфраструктура: Vite, monorepo, CI∕CD · ← Предыдущая · → Следующая

Желательно~3 мин чтенияУровень: middle

Зачем это на собесе

Организация нескольких приложений и библиотек в одном репозитории.

Объяснение

Monorepo — один репозиторий для нескольких пакетов/приложений (web, admin, ui-kit, api-client, конфигурации).

ПлюсыМинусы
атомарные изменения по нескольким пакетамразмер репозитория, время CI без кэша
единые версии зависимостей и настройкиправа доступа (всё в одном репозитории)
простой шаринг кода без публикациисложнее онбординг
единые CI/линтеры/скриптынужны инструменты (кэш, affected)
apps/web, apps/admin
packages/ui, packages/api-client, packages/config-eslint, packages/config-ts
pnpm-workspace.yaml, package.json, turbo.json / nx.json, tsconfig.base.json
# pnpm-workspace.yaml
packages: ["apps/*", "packages/*"]
// apps/web/package.json
{ "dependencies": { "@acme/ui": "workspace:*", "@acme/api-client": "workspace:*" } }
ИнструментРоль
pnpm workspacesустановка и связывание пакетов (workspace:*), pnpm -F web build, pnpm -r test
Turborepoоркестрация задач (turbo run build test lint), граф зависимостей, кэш результатов (локальный и удалённый), параллелизм
Nxто же + генераторы, affected (только затронутые проекты), графы, плагины, module boundaries
Lernaпубликация версий (сейчас поверх Nx)
Changesetsверсионирование и changelog
// turbo.json
{ "tasks": { "build": { "dependsOn": ["^build"], "outputs": ["dist/**"] }, "test": { "dependsOn": ["build"] }, "lint": {}, "dev": { "cache": false, "persistent": true } } }

Практики:

  • Внутренние пакеты — TypeScript-проекты (references) или исходники без сборки (exports на src) с Vite alias.
  • Единые конфиги (ESLint, Prettier, tsconfig) как пакеты.
  • Affected: в CI запускать только затронутые задачи.
  • Кэш сборки/тестов (Remote Cache) сокращает CI в разы.
  • Границы модулей: правила импортов (nx enforce-module-boundaries, ESLint).
  • Версионирование: независимое или фиксированное, Changesets.

Нюансы и подводные камни

  • Циклические зависимости между пакетами.
  • «Фантомные» зависимости: пакет использует зависимость, объявленную не у себя (pnpm строгий — помогает).
  • Единая версия зависимости на весь репозиторий vs потребности приложений.
  • Без кэша и affected CI становится очень медленным.
  • Монорепо не отменяет границ: без правил всё связывается со всем.

Практика

  1. Создайте pnpm workspace с приложением и общим ui пакетом.
  2. Настройте Turborepo с кэшем и dependsOn.
  3. Запустите в CI только затронутые пакеты.

Вопросы с ответами

Связанные темы