An open API service indexing awesome lists of open source software.

https://github.com/zmitry/monorepo-guide


https://github.com/zmitry/monorepo-guide

Last synced: 11 months ago
JSON representation

Awesome Lists containing this project

README

          

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

## 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 ..0 --skip-git --skip-npm
```

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