Comments 8
Монорепы шагают по планете. Вы на Bazel не смотрели? Если смотрели, то какие плюсы, минусы, подводные камни? С NPM он работает уже достаточно хорошо и умеет не перезапускать незатронутые изменениями тесты, не говоря уже о большей универсальности относительно количества поддерживаемых языков и пакетных репозиториев.
И ещё, как вы поднимаете версии зависимостей, когда новая версия ломает тесты во многих местах в монорепе? Чинит тесты и код тот, кому нужно версию поднять или созывается весь колхоз и каждый в своей зоне ответственности работает?
В случае, если кто-то сломал тест или код, то, согласно соседскому соглашению, он его и чинит. У нас эта практика распространяется не только наш монореопзиторий, но и на другие проекты. Плюс, в случае монорепозитория CI настроен таким образом, что без прохождения всех тестов, смержить пул-реквест не получится. Если есть вопросы о том, каким образом лучше внести правки, то разработчик, который лучше разбирается, может помочь, но сами исправления все равно остаются на том, кто сломал.
Плюс, в случае монорепозитория CI настроен таким образом, что без прохождения всех тестов, смержить пул-реквест не получится. Если есть вопросы о том, каким образом лучше внести правки, то разработчик, который лучше разбирается, может помочь, но сами исправления все равно остаются на том, кто сломал.
Мы пришли к коллаборативным PR, когда в один PR коммитит много людей. Но размер нашего репозитория очень большой. Вот мне и интересно стало, использует ли кто-нибудь ещё коллаборативные PR.
В моей жизни были монорепы, где каждый сам чинил тесты других проектов вокруг. Начиная с определенного размера репы подход начинал жестко тормозить разработчиков, потому что они закапывались в чужой код при исправлении тестов. И возникла ещё психологическая проблема — программисты чаще отказывались от подъемов версий внешних зависимостей, потому что представляли себе сколько тестов надо будет чинить.
А с вашим случаем помогите до конца разобраться, потому что не понял в чем описанная проблема.
Сразу скажу, что в Lerna не шарю, но про Bazel могу сказать, что он совершенно точно синхронизирует все зависимости без участия разработчика. Если на пальцах:
1) Вы подсовываете Bazel один package.json или вообще lock-файл, в котором описаны все внешние зависимости монорепы, дальше происходит магия и внешние зависимости становятся доступны системе сборки как если бы они лежали локально в монорепе. После этого вы начинаете жить в герметичном мире, где все внешние пакеты нужных версий зафиксированы и живут рядом с вашими внутренними пакетами.
2) Ваши внутренние пакеты описываются BUILD.bazel файлами. В них указываются зависимости внутреннего пакета от других пакетов, внутренних и импортированных в п.1 внешних. Цель сборки в синтаксисе Bazel выглядит как-то так, немного упрощенно:
js_library(
name = "my-shiny-component",
srcs = "*.js",
deps = [
"//monorepa/components/another-shiny-component",
"//monorepa/components/not-so-shiny-one",
"@npm//sass-loader",
"@npm//vue",
],
)
Все это порождает граф зависимостей (и сборки), которым очень легко рулить и можно не заниматься пересборкой пакетов, которые пересобирать не нужно. Есть ли в такой модели что-то, чего вам не хватает и что есть в Lerna?
Если я правильно понял, то Bazel — это инструмент для синхронизации и сборки проектов, и работает Bazel в основном как раз с собранными проектом. Сборка проектов в нашем репозитории идет от внутреннего инструмента для бойлерплейтинга (вот здесь можно подробнее о нем узнать ) и этот инструмент учитывает особенности сборки основного монолита. Поэтому нам нужен был инструмент только для синхронизации версий. Lerna работает таким образом, что зависимости внешние могут быть вынесены на корневой уровень монорепозитория, а внутренние зависимости связаны через ссылки. Благодаря такому механизму нам удалось в какой-то момент избавиться от package-lock файлов в наших пакетах, оставив только один lock файл в корне. Плюс, кроме синхронизации, Lerna позволяет автоматизировать работу именно с изменением версий пакетов. Так, к примеру, с помощью двух команд можно узнать какие пакеты были изменены, где и как необходимо изменить версии (поднять патч, минорную или мажорную версию), а затем опубликовать пакеты. И в данном случае синхронизация позволила решить проблему построения явного дерева зависимостей, которое может быть автоматически измененно, а автоматизация упростила работу с монорепозитрием, сведя до работы с небольшим набором команд. Если я правильно понимаю, то в Bazel нет механизма для автоматизации работы именно с версиями пакетов. Кроме того, отмечу что наш монорепозитрой нужен для разработки без сборки, так как пакеты из него еще нужны в основной кодовой базе монолита, в которой настроена и работает своя сборка проекта.
Rush выглядит интересным решением. Когда только обсуждали решение о внедрении Lerna, Rush не рассматривали. Сейчас выглядит так, что то, что решает наш скрипт для поднятия версий, уже решено в Rush. Сам не пользовался этим инструментом, но он выглядит интересным
Организация кодовой базы и тестирования в монорепозитории