https://github.com/zmitry/monorepo-guide
https://github.com/zmitry/monorepo-guide
Last synced: 11 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/zmitry/monorepo-guide
- Owner: zmitry
- Created: 2018-03-03T16:13:55.000Z (over 8 years ago)
- Default Branch: master
- Last Pushed: 2018-03-14T09:09:14.000Z (about 8 years ago)
- Last Synced: 2025-04-08T21:14:45.378Z (about 1 year ago)
- Size: 6.84 KB
- Stars: 5
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
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