Назад к блогу
DevOps

Монорепозитории: Turborepo, Nx и организация кода

Организация кода в монорепозитории: Turborepo и Nx, workspace, общие пакеты, зависимости и CI/CD для monorepo.

5 января 2026 г.
11 мин чтения
397 просмотров
MOLOTILO

MOLOTILO DIGITAL

Монорепозитории: Turborepo, Nx и организация кода

Что такое монорепозиторий

Monorepo — подход, при котором несколько проектов хранятся в одном репозитории. Это упрощает переиспользование кода, синхронизацию зависимостей и атомарные изменения.

Преимущества monorepo

  • Общие пакеты — переиспользование кода между проектами
  • Атомарные изменения — один PR для связанных изменений
  • Единые зависимости — одна версия библиотек
  • Упрощённый рефакторинг — изменения видны сразу везде

Структура monorepo

my-monorepo/
├── apps/
│   ├── web/              # Next.js frontend
│   ├── admin/            # Admin panel
│   ├── api/              # Backend API
│   └── mobile/           # React Native app
├── packages/
│   ├── ui/               # Общие UI компоненты
│   ├── utils/            # Утилиты
│   ├── config/           # Общие конфиги (ESLint, TS)
│   └── database/         # Prisma схема и клиент
├── turbo.json
├── package.json
└── pnpm-workspace.yaml

Turborepo — быстрая сборка

Turborepo — инструмент для оптимизации сборки monorepo:

// turbo.json
{
  "$schema": "https://turbo.build/schema.json",
  "globalDependencies": ["**/.env.*local"],
  "pipeline": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": [".next/**", "dist/**"]
    },
    "lint": {
      "dependsOn": ["^lint"]
    },
    "dev": {
      "cache": false,
      "persistent": true
    },
    "test": {
      "dependsOn": ["build"],
      "outputs": ["coverage/**"]
    }
  }
}
// package.json (root)
{
  "name": "my-monorepo",
  "private": true,
  "scripts": {
    "build": "turbo run build",
    "dev": "turbo run dev",
    "lint": "turbo run lint",
    "test": "turbo run test"
  },
  "devDependencies": {
    "turbo": "^1.10.0"
  }
}

// pnpm-workspace.yaml
packages:
  - "apps/*"
  - "packages/*"

Общие пакеты

// packages/ui/package.json
{
  "name": "@repo/ui",
  "version": "0.0.0",
  "main": "./src/index.ts",
  "types": "./src/index.ts",
  "exports": {
    ".": "./src/index.ts",
    "./button": "./src/button.tsx",
    "./card": "./src/card.tsx"
  }
}

// packages/ui/src/button.tsx
export interface ButtonProps {
  children: React.ReactNode;
  variant?: 'primary' | 'secondary';
  onClick?: () => void;
}

export function Button({ children, variant = 'primary', onClick }: ButtonProps) {
  return (
    <button
      className={`btn btn-${variant}`}
      onClick={onClick}
    >
      {children}
    </button>
  );
}

// packages/ui/src/index.ts
export * from './button';
export * from './card';
export * from './input';

// Использование в apps/web
// apps/web/package.json
{
  "dependencies": {
    "@repo/ui": "workspace:*",
    "@repo/utils": "workspace:*"
  }
}

// apps/web/app/page.tsx
import { Button, Card } from '@repo/ui';
import { formatDate } from '@repo/utils';

Nx — альтернатива Turborepo

# Создание Nx workspace
npx create-nx-workspace@latest my-workspace

# Генерация приложений
nx generate @nx/next:application web
nx generate @nx/node:application api

# Генерация библиотеки
nx generate @nx/react:library ui

# Запуск
nx serve web
nx build api
nx affected:test  # Тестирует только изменённое
// nx.json
{
  "targetDefaults": {
    "build": {
      "dependsOn": ["^build"],
      "cache": true
    },
    "test": {
      "cache": true
    }
  },
  "affected": {
    "defaultBase": "main"
  }
}

CI/CD для monorepo

# .github/workflows/ci.yml
name: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0  # Нужно для affected
      
      - uses: pnpm/action-setup@v2
        with:
          version: 8
      
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'pnpm'
      
      - name: Install dependencies
        run: pnpm install
      
      # Turborepo кэширование
      - name: Cache turbo
        uses: actions/cache@v3
        with:
          path: .turbo
          key: turbo-${{ github.sha }}
          restore-keys: turbo-
      
      - name: Build
        run: pnpm build
      
      - name: Test
        run: pnpm test
      
      - name: Lint
        run: pnpm lint

Управление зависимостями

# Установка зависимости в конкретный пакет
pnpm add lodash --filter @repo/utils

# Установка dev зависимости в root
pnpm add -D typescript -w

# Обновление всех зависимостей
pnpm update -r

# Проверка дублирующихся зависимостей
pnpm dedupe

Заключение

Monorepo упрощает управление связанными проектами. Turborepo и Nx обеспечивают быструю сборку через кэширование и параллелизацию. Начните с простой структуры и масштабируйте по мере роста.

Monorepo — это не серебряная пуля. Используйте его, когда проекты тесно связаны и часто меняются вместе.

MonorepoTurborepoNxWorkspaceCI/CD

Понравилась статья?

Подпишитесь на наш блог, чтобы не пропустить новые материалы