{"id":21977412,"url":"https://github.com/zmitry/monorepo-guide","last_synced_at":"2025-07-07T19:40:46.629Z","repository":{"id":110953778,"uuid":"123708516","full_name":"zmitry/monorepo-guide","owner":"zmitry","description":null,"archived":false,"fork":false,"pushed_at":"2018-03-14T09:09:14.000Z","size":7,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-08T21:14:45.378Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zmitry.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-03-03T16:13:55.000Z","updated_at":"2024-07-01T14:23:34.000Z","dependencies_parsed_at":"2024-02-24T00:45:40.763Z","dependency_job_id":null,"html_url":"https://github.com/zmitry/monorepo-guide","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/zmitry/monorepo-guide","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zmitry%2Fmonorepo-guide","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zmitry%2Fmonorepo-guide/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zmitry%2Fmonorepo-guide/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zmitry%2Fmonorepo-guide/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zmitry","download_url":"https://codeload.github.com/zmitry/monorepo-guide/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zmitry%2Fmonorepo-guide/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264139556,"owners_count":23563246,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-29T16:14:36.166Z","updated_at":"2025-07-07T19:40:46.623Z","avatar_url":"https://github.com/zmitry.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Гайд по орагнизации монорепозитория\n\n## overview\n\n* Зачем ?\n* Инструменты и способы ораганизации\n* Сравнение инструментов\n* Примеры\n* Полезные ссылки\n\n## Зачем ?\n\nМонорепозиторий это способ организации когда, когда все разрабатываемые пакети и приложения находятся в единственном репозитории.\nВ чем преимущества перед обычной стратегией manyrepos ?\n\n1.  Все процессы и изменения в репозиторий являются централизоваными.\n2.  Тестирование и разработка связных компонентов приложения упрощается в разы.\n3.  Упрощается настройка ci и тестов для репозитория т.к их нужно настроить только один раз.\n4.  Упрощается процесс код ревью.\n5.  При изменениях которые задевают несколько компонентов нужно создавать и ревьювить только один пул реквест.\n6.  Комплексное тестирование на ci значително упрощается.\n\nИз минусов можно вынести:\n\n1.  Размер репоозитория очень быстро вырастает.\n2.  История изменений может быть весьма запутанной.\n3.  Если в монорепозитории находятся конечные приложения, то способ деплой может быть своеобразным\n\nЧто же даст переход на монорепозиторий ?\n\n* Упрощение вокрфлоу,\n* ускорения работы в постоянном меняющейся базе кода\n* уменьшение количества файлов и зависимостей для разработки (prettier,eslint, husky .etc)\n\n## Инструменты и способы ораганизации\n\n### Вариант 1\n\nСамый базовый случай использования монорепозитория это просто создать папку pacakges и при деплое приложения скачаевается вся папка, а зависимости подтягиваются с это папки.\n\nСначала рассмотрим 1 вариант. У вас все пакеты находятся в одном репозитории и модификация модулей происходит только с монорепозитория. В таком случае для управления пакетами следует присмотреться к таким тулзам как lerna, yarn workspaces, bolt, oao, rush(). Эти инстурменты упрощают работу с множеством модулей, в особенности такие процессы как линкование зависимостей между модулями, уставновка дополнительных пакетов для модулей, массовые действия с пакетами.\n\nТак же у вас может быть, что в монорепозитории вы развиваете библиотеку компонентов, которую потом используют ваши приложения в данном случае вам нужно делать publish компонентов в npm registry или свой собственный, а в зависящих приложениях модули уже будут скачиваться с помощью npm. C релизом и паблишем пакетов может помочь lerna, которая упрощает процес паблишинга модулей и апдейта зависимостей между модулями.\n\n### Вариант 2\n\nБолее сложный вариант, когда работа с модулем идет в две стороны как с монорепозитория, так и с отдельного репозитория для этого модуля.\nПример, вы создали библиотеку которую активно развивали в контексте вашего приватного монорепозитория, но потом сделали ее опенсорсной и вам нужно синхронизировать код между гитхабом и вашим монорепозиторием.\n\n\n\n## Структура монорепозитория\n\n```\napps/\n    app1/ --\u003e git/remotes/app1.git\n    app2/ --\u003e git/remotes/app2.git\n    app3/ --\u003e git/remotes/app3.git\n    app4/ --\u003e git/remotes/app4.git\ncomponents/\n    comp1/\n    comp2/\n    comp3/\n```\n\nАпликейшины и компоненты находятся в одном репозитории и не имеют вложенных репозиториев.\nКомпоненты не имеют никаких признаков самостоятельных репозиториев, в них лежат только нужные для них файлы т.е (Readme.md, package.json, тесты и код компонента).\n\nВ руте репозитория находятся файлы которые проверяют код стайл и прекомит хуки.\nПрекоммит хуки находятся в scripts/hooks.\nК вспомагательным файлам относятся .prettierrc, eslintrc, .npmrc, .env, lerna.json - эти файлы одни и относятся ко всем апликейшинам и компонентам.\n\nАпликейшины в свою очередь являются полусамостоятельными репозиториями в которых есть ci для тестов (тесты запускаются при пуше в монорепозиторий или при пуше в отдельный репозиторий апликейшина) и все зависимости которые надо для апликейшинов. Репозитории апликейшинов являются read-only и если там происходят какие-то изменения, то синхронизация происходит вручную.\n\n## Организация работы\n\nУстановка зависимостей для всех апликейшинов работает через yarn workspaces, которые находятся в package.json, проперти workspaces. Проперти packages это массив [glob](\u003chttps://en.wikipedia.org/wiki/Glob_(programming)\u003e), который указывает где находятся наши пакеты.\nПроперти nohoist это тоже набор glob, который отвечает за то, какие пакеты не надо поднимать в рутовый package json. Т.е если указать nohoist: [\"**/webpack\"], то в каждом пакете где указан вебпак, он не будет подниматься в рутовые node_modules\n\n## Ci\n\nДля всех пакетов настроен ci, при пуше со своей ветке определяются компоненты которые изменились и для них запускаются тесты. Делается это через lerna updated, лерна находит для каждого пакета последню метку с версией и сравнивает были ли изменения, которые касались этого пакета после этого.\nЕсли на отдельной ветке были изменения все компонентов, то все последующие пуши в эту ветку будут тригерить запуск тестов во всех компонентах.\n\nПри мерже ветки в ветку мастер вызывается паблиш компонентов которые поменялись. Для компонентов это паблиш в npm registry, а для всех пакетов с private:true происходит пуш в собственный репозиторий этого апликейшина.\n\n## Git split\n\nС помощью технологии git subtree split (или более быстрой версии splitsh/lite) происходит разбор гитовой истории и создание новой истории которая относится только к определенной подпапке апликейшина.\nт.е при мерже в мастер, мы делаем сплит истории для апликейшинов и пушим их в отельный репозиторий или можем выделить в отдельную ветку, но при этом у нас там будут файлы которые относятся, только к апликейшину и никакой инфы про монорепозиторий.\n\n## INFO\n\n### запуск со своей ветки\n\n1. нужно запаблишить пакеты с приставкой альфа `lerna publish --beta --force-publish=\"*\"`\n2. в ручную запушить апликейшин на свою ветку через git-split --prefix \"./apps/alto-base\" --target=\"refs/heads/branch-name\"\n3. выбрать эту ветку на ci и задеплоить\n\n### если что-то пошло не так с запаблишеными версиями или с деплоем\n\nпишем команду\n\n```\nlerna publish --force-publish=\"*\" --exact --repo-version \u003ccurrent\u003e.\u003cversion\u003e.0 --skip-git --skip-npm\n```\n\nсurrent - мажорная версия текущего пакета\nvarsion - максимальная минорная версия среди всех пакетов + 1\nнапример версия пакета А - 2.4, версия И - 2.7 то версия с которой надо исправлять 2.8\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzmitry%2Fmonorepo-guide","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzmitry%2Fmonorepo-guide","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzmitry%2Fmonorepo-guide/lists"}