Здравейте всички!
В тази статия искам да покажа как можем да създадем monorepo с Golang и Bazel.
Изисквания:
- Go Modules — искаме да използваме
go mod
за управление на зависимости - Споделена кодова база — искаме да използваме повторно нашия код в друго приложение
- Тест — искаме да проведем тестове на едно/всички приложения
- Изграждане — искаме да изграждаме всяко приложение отделно
Тези изисквания надхвърлят определението за monorepo. Добре, да започваме.
1. Init go модули
Трябва да създадем go mod в нашата папка:
go mod init monorepo
След тази команда можем да получим зависимост от нашия проект.
2. Създайте например две приложения
Нека създадем папка packages
, която ще съдържа всички наши приложения.
mkdir packages cd packages mkdir main_app mkdir second_app cd main_app && touch main.go && cd ../ cd second_app && touch main.go && cd ../ mkdir shared && touch shared.go - that file for shared code
Например, нашето приложение ще използва gin като HTTP сървър:
go get github.com/gin-gonic/gin
3. Създайте работно пространство за нашето monorepo
В главната папка трябва да създадем файл WORKSPACE със съдържание:
И BUILD файл със съдържание:
След като имаме нужда от настройка на Bazel да използва зависимост от go.mod
с команда:
bazel run //:gazelle -- update-repos -from_file=go.mod
Тази команда ще актуализира нашия файл WORKSPACE със зависимости от go.mod
Завършваме настройката на нашето работно пространство, след което трябва да настроим нашите приложения.
4. Създайте компилация за приложения
Всяко приложение в папката на приложението трябва да има BUILD като входна точка за Bazel
Тук имаме два раздела:
- go_binary
- go_test
Секция go_binary
Този раздел има пълен списък с полета, който можете да намерите във връзката. Ще опиша само някои от тях:
„name“ — името за Bazel, за deps и Bazel resolver
“srcs” — входни точки за модули, ще бъдат като артефакти
“importpath” — как трябва да импортираме този модул в нашите приложения
“deps” — масив от зависимости
Раздел go_test
„име“ — за теста за изпълнение
“srcs” — входни точки за тестове
Нека добавим малко споделено съдържание
За създаване на приложение като в реалния живот добавям рутер и в двете приложения с подобно съдържание
Ако видите, че този пакет използва някои зависимости от споделена папка.
И нека създадем BUILD файл за този пакет:
Този файл има раздел „go_library“
Секция go_library
„име“ — името за Bazel, за използване в dep
“srcs” — входната точка за lib
„importpath“ — път за импортиране извън (Bazel ще бъде разрешен този псевдоним като webpack в nodejs)
“visibility” — видимост на модула в Bazel
„deps“ — зависимости, в този пример имаме dep от „@com_github_gin_gonic_gin“ — това е вътрешното име на gin, което можете да получите от файла WORKSPACE и от нашия споделен манипулатор.
5. Създайте споделена папка и компилирайте
В предишната стъпка имаме препратка към споделена папка.
Създавам споделен манипулатор за джин като този:
И компилирайте за пакет:
Както виждаме и джин в деп.
Ще пропусна частта в създаването на код за второто приложение, защото е напълно същото. Пълният код можете да намерите тук
6. Нека изградим и тестваме нашите приложения
За изграждане на основно приложение можем да използваме командата:
bazel build //packages/main_app:main_app
Тази команда ще бъде приложение за изграждане и ще покаже пътя до bin файла
За изграждане на второ приложение можете да използвате:
bazel build //packages/second_app:second_app
Тест
Тест за едно приложение:
bazel test //packages/second_app/...:all
Всички приложения тестват:
bazel test //packages/...:all
Dep графика
Bazel може да създаде dep графика с командата:
bazel query 'allpaths(packages/...,//packages/shared/handlers/health:health)' --output graph | dot -Tpng > dep.png
Тази команда ще покаже всички пакети, които зависят от модула здраве.
7. Насладете се!
В този пример показах основата за създаване на monorepo в Go, ако се интересувате, ще продължа статията и ще кажа как да използвате например protobuf или общи статични файлове в monorepo.