Monorepo: pnpm workspaces, Nx, Turborepo
↑ 6.2 Сборка и инфраструктура: Vite, monorepo, CI∕CD · ← Предыдущая · → Следующая
Зачем это на собесе
Организация нескольких приложений и библиотек в одном репозитории.
Объяснение
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 становится очень медленным.
- Монорепо не отменяет границ: без правил всё связывается со всем.
Практика
- Создайте pnpm workspace с приложением и общим
uiпакетом. - Настройте Turborepo с кэшем и
dependsOn. - Запустите в CI только затронутые пакеты.
Вопросы с ответами
Зачем monorepo?
Общий код и конфигурации, атомарные изменения по нескольким пакетам, единый CI.
Что делает Turborepo/Nx?
Оркестрируют задачи по графу зависимостей, кэшируют результаты и запускают только затронутое.