Skip to content

Latest commit

 

History

History
110 lines (73 loc) · 10.2 KB

Monorepo.md

File metadata and controls

110 lines (73 loc) · 10.2 KB

Гайд по орагнизации монорепозитория

overview

  • Зачем ?
  • Инструменты и способы ораганизации
  • Сравнение инструментов
  • Примеры
  • Полезные ссылки

Зачем ?

Монорепозиторий это способ организации когда, когда все разрабатываемые пакети и приложения находятся в единственном репозитории. В чем преимущества перед обычной стратегией manyrepos ?

  1. Все процессы и изменения в репозиторий являются централизоваными.
  2. Тестирование и разработка связных компонентов приложения упрощается в разы.
  3. Упрощается настройка ci и тестов для репозитория т.к их нужно настроить только один раз.
  4. Упрощается процесс код ревью.
  5. При изменениях которые задевают несколько компонентов нужно создавать и ревьювить только один пул реквест.
  6. Комплексное тестирование на ci значително упрощается.

Из минусов можно вынести:

  1. Размер репоозитория очень быстро вырастает.
  2. История изменений может быть весьма запутанной.
  3. Если в монорепозитории находятся конечные приложения, то способ деплой может быть своеобразным

Что же даст переход на монорепозиторий ?

  • Упрощение вокрфлоу,
  • ускорения работы в постоянном меняющейся базе кода
  • уменьшение количества файлов и зависимостей для разработки (prettier,eslint, husky .etc)

Инструменты и способы ораганизации

Вариант 1

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

Сначала рассмотрим 1 вариант. У вас все пакеты находятся в одном репозитории и модификация модулей происходит только с монорепозитория. В таком случае для управления пакетами следует присмотреться к таким тулзам как lerna, yarn workspaces, bolt, oao, rush(). Эти инстурменты упрощают работу с множеством модулей, в особенности такие процессы как линкование зависимостей между модулями, уставновка дополнительных пакетов для модулей, массовые действия с пакетами.

Так же у вас может быть, что в монорепозитории вы развиваете библиотеку компонентов, которую потом используют ваши приложения в данном случае вам нужно делать publish компонентов в npm registry или свой собственный, а в зависящих приложениях модули уже будут скачиваться с помощью npm. C релизом и паблишем пакетов может помочь lerna, которая упрощает процес паблишинга модулей и апдейта зависимостей между модулями.

Вариант 2

Более сложный вариант, когда работа с модулем идет в две стороны как с монорепозитория, так и с отдельного репозитория для этого модуля. Пример, вы создали библиотеку которую активно развивали в контексте вашего приватного монорепозитория, но потом сделали ее опенсорсной и вам нужно синхронизировать код между гитхабом и вашим монорепозиторием.

Структура монорепозитория

apps/
    app1/ --> git/remotes/app1.git
    app2/ --> git/remotes/app2.git
    app3/ --> git/remotes/app3.git
    app4/ --> git/remotes/app4.git
components/
    comp1/
    comp2/
    comp3/

Апликейшины и компоненты находятся в одном репозитории и не имеют вложенных репозиториев. Компоненты не имеют никаких признаков самостоятельных репозиториев, в них лежат только нужные для них файлы т.е (Readme.md, package.json, тесты и код компонента).

В руте репозитория находятся файлы которые проверяют код стайл и прекомит хуки. Прекоммит хуки находятся в scripts/hooks. К вспомагательным файлам относятся .prettierrc, eslintrc, .npmrc, .env, lerna.json - эти файлы одни и относятся ко всем апликейшинам и компонентам.

Апликейшины в свою очередь являются полусамостоятельными репозиториями в которых есть ci для тестов (тесты запускаются при пуше в монорепозиторий или при пуше в отдельный репозиторий апликейшина) и все зависимости которые надо для апликейшинов. Репозитории апликейшинов являются read-only и если там происходят какие-то изменения, то синхронизация происходит вручную.

Организация работы

Установка зависимостей для всех апликейшинов работает через yarn workspaces, которые находятся в package.json, проперти workspaces. Проперти packages это массив glob, который указывает где находятся наши пакеты. Проперти nohoist это тоже набор glob, который отвечает за то, какие пакеты не надо поднимать в рутовый package json. Т.е если указать nohoist: ["**/webpack"], то в каждом пакете где указан вебпак, он не будет подниматься в рутовые node_modules

Ci

Для всех пакетов настроен ci, при пуше со своей ветке определяются компоненты которые изменились и для них запускаются тесты. Делается это через lerna updated, лерна находит для каждого пакета последню метку с версией и сравнивает были ли изменения, которые касались этого пакета после этого. Если на отдельной ветке были изменения все компонентов, то все последующие пуши в эту ветку будут тригерить запуск тестов во всех компонентах.

При мерже ветки в ветку мастер вызывается паблиш компонентов которые поменялись. Для компонентов это паблиш в npm registry, а для всех пакетов с private:true происходит пуш в собственный репозиторий этого апликейшина.

Git split

С помощью технологии git subtree split (или более быстрой версии splitsh/lite) происходит разбор гитовой истории и создание новой истории которая относится только к определенной подпапке апликейшина. т.е при мерже в мастер, мы делаем сплит истории для апликейшинов и пушим их в отельный репозиторий или можем выделить в отдельную ветку, но при этом у нас там будут файлы которые относятся, только к апликейшину и никакой инфы про монорепозиторий.

INFO

запуск со своей ветки

  1. нужно запаблишить пакеты с приставкой альфа lerna publish --beta --force-publish="*"
  2. в ручную запушить апликейшин на свою ветку через git-split --prefix "./apps/alto-base" --target="refs/heads/branch-name"
  3. выбрать эту ветку на ci и задеплоить

если что-то пошло не так с запаблишеными версиями или с деплоем

пишем команду

lerna publish --force-publish="*" --exact --repo-version <current>.<version>.0 --skip-git --skip-npm

сurrent - мажорная версия текущего пакета varsion - максимальная минорная версия среди всех пакетов + 1 например версия пакета А - 2.4, версия И - 2.7 то версия с которой надо исправлять 2.8