Monorepo с Lerna/Nx

Monorepo представляет собой подход к управлению несколькими проектами в одном репозитории, что позволяет централизованно управлять зависимостями, инструментами сборки и версионностью. В экосистеме Vue.js использование Monorepo особенно удобно для крупных проектов, состоящих из нескольких библиотек компонентов, приложений и сервисов. Основными инструментами для управления Monorepo являются Lerna и Nx.


Основные преимущества Monorepo

  • Единая версия зависимостей. Все пакеты используют одинаковые версии библиотек, что снижает риск конфликтов.
  • Централизованное тестирование. Общие тесты и интеграционные проверки могут выполняться для всех пакетов сразу.
  • Повторное использование компонентов. Общие Vue-компоненты и утилиты можно хранить в одном месте и подключать в разные приложения.
  • Ускорение сборки. Современные инструменты, такие как Nx, поддерживают кэширование и параллельную сборку пакетов.

Структура Monorepo

Пример базовой структуры Monorepo для Vue.js с Lerna:

my-monorepo/
├── packages/
│   ├── ui-components/        # Общие Vue-компоненты
│   ├── utils/                # Утилиты и хелперы
│   └── app/                  # Основное Vue-приложение
├── package.json
├── lerna.json
└── tsconfig.base.json
  • packages/ – директория с пакетами, каждый пакет имеет собственный package.json.
  • lerna.json – конфигурация Lerna: версии, стратегия публикации, пути к пакетам.
  • tsconfig.base.json – общий конфигурационный файл TypeScript, если проект использует TypeScript.

Настройка Lerna

Установка и инициализация:

npm install --global lerna
lerna init

lerna.json может выглядеть так:

{
  "packages": ["packages/*"],
  "version": "independent",
  "npmClient": "npm",
  "useWorkspaces": true
}
  • "version": "independent" — каждая библиотека может иметь собственную версию.
  • "useWorkspaces": true — интеграция с Yarn/NPM workspaces для централизованного управления зависимостями.

Добавление пакета в Monorepo:

lerna create ui-components packages/ui-components

Команды для работы с Monorepo:

  • lerna bootstrap – устанавливает все зависимости между пакетами.
  • lerna run build – выполняет команду build во всех пакетах.
  • lerna publish – публикует пакеты в npm с учетом версий.

Настройка Nx

Nx предоставляет более мощный инструмент для управления Monorepo, включая генерацию приложений и библиотек, продвинутый кэш и CI/CD интеграцию.

Инициализация Nx:

npx create-nx-workspace@latest my-monorepo

При выборе шаблона необходимо указать поддержку Vue.js. Структура Nx отличается от Lerna:

my-monorepo/
├── apps/
│   └── main-app/             # Основное Vue-приложение
├── libs/
│   ├── ui-components/        # Общие компоненты
│   └── utils/                # Утилиты
├── nx.json
├── package.json
└── tsconfig.base.json
  • apps/ — конечные приложения.
  • libs/ — переиспользуемые библиотеки и модули.
  • nx.json — конфигурация Nx, управление зависимостями между проектами.
  • tsconfig.base.json — общий TypeScript конфиг.

Генерация и использование библиотек Vue

Создание новой библиотеки в Nx:

nx generate @nx/vue:lib ui-components
  • Автоматически создается структура с package.json, тестами и базовым компонентом.
  • Для использования в приложении:
import { MyButton } from '@my-monorepo/ui-components';
  • Nx поддерживает dependency graph, что позволяет видеть, какие библиотеки зависят друг от друга и оптимизировать сборку.

Сборка и тестирование

Lerna и Nx предоставляют команды для сборки и тестирования пакетов:

  • Lerna: lerna run build, lerna run test
  • Nx: nx build <project>, nx test <project>, nx affected:build (только измененные пакеты)

Nx позволяет выполнять сборку и тесты только для измененных пакетов, что значительно ускоряет процесс CI/CD в больших Monorepo.


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

  • Версии пакетов: Lerna поддерживает фиксированные версии и независимые версии для пакетов.
  • Workspaces: Использование Yarn/NPM workspaces позволяет устанавливать зависимости централизованно и избегать дублирования.
  • Peer Dependencies: Для общих Vue-библиотек рекомендуется использовать peerDependencies для Vue и сопутствующих библиотек, чтобы приложения не включали несколько копий Vue.

Интеграция с CI/CD

  • Nx предоставляет встроенную интеграцию с GitHub Actions, GitLab CI и другими системами.
  • Команда nx affected:* позволяет запускать сборку, тесты и линтер только для измененных проектов.
  • Кэширование результатов сборки и тестирования значительно снижает время выполнения пайплайнов.

Рекомендации по организации Vue Monorepo

  • Разделять приложения и библиотеки по функциональному признаку.
  • Использовать единый стиль кодирования и конфигурацию линтера.
  • Поддерживать тесты на уровне библиотек, а не только приложений.
  • Применять Nx для больших проектов с множеством пакетов, Lerna — для более простых Monorepo.

Эта структура и инструменты обеспечивают масштабируемость, удобство поддержки и ускоряют разработку крупных Vue.js проектов в Monorepo.