На DataForm Мы поддерживаем несколько пакетов NPM и сайт документации в одном монорепом и мы делаем все это с Базель Отказ
Я собираюсь быстро поговорить через монорепозию и базель, затем глубокий погружение в интересные части нашего монорепо с некоторыми настоящими примерами кода, покрывающих:
- Bazel Teamescripts Основы
- Управление несколькими пакетами в одном монорепо
- Строительство и публикация пакетов NPM с базелем
Наш проект — это открытый источник, поэтому вы можете просматривать весь код или клон и построить его с Bazel AT: https://github.com/dataform-co/dataform
Весь ваш код в одном репо
a.k.a monoRepo, так жарко прямо сейчас Отказ
Раньше я работал в Google, поэтому я могу быть предвзятым, но есть огромное количество ценности, чтобы иметь весь свой код в одном одном репозитории. Вы в конечном итоге проводят намного меньше времени, выполняя повторяющиеся задачи, обновляющие подмодулы GIT, нажав новые пакеты, бегущие сценарии Bash — такие вещи, которые отвлекают вас от важной задачи под рукой.
С одной базой кодовой базы становится очень легко повторно использовать код и библиотеки между различными проектами, но Вам нужна хорошая система сборки, чтобы сделать его работу Отказ
Базель
_ {Fast, исправь} - выберите два_ — https://bazel.build.
Вы когда-нибудь пытались клонировать и компилировать REPO Source Source, чтобы провести 30 минут, пропавшие без пропавших или сломанных системных зависимостей, несоответствующими версиями и множеством сценариев Bash, которые просто не работают? Да…
Базель — это система сборки. Это весьма самоуверенно и хитрость мастеру, но оставляет вас чрезвычайно быстрым, герметичным и воспроизводимым процессом сборки после принятия.
Базель все еще довольно молод, но экосистема развивается чрезвычайно быстро. Он также построен на прочных фундаментах — использование внутренне в Google Bazel называется Blaze и помогает власть одному колоссальному монорепому Poogle (буквально весь код).
Эта проблема
Мы поддерживаем несколько пакетов NPM с межведомственными зависимостями. Наши цели здесь:
- Управлять всеми пакетами в одном репозитории
- Для наших строгий быть быстрым и надежным
- Чтобы проверить изменения в нескольких пакетах одновременно
- Простой способ управлять версиями по всем этим пакетам
- Чтобы написать как можно меньше скриптов Bash
Базовая базельское правило TS
Вот пример того, как вы построете TyplectScript Library с Bazel. Наш простейший пакет в репо @ DataForm/Core И мы будем использовать это в качестве примера для большинства постов.
Папка выглядит как обычный пакет TS, кроме Построить файл. Вот часть этого файла, который фактически компилирует Tymdercript:
ts_library(
name = "core",
srcs = glob(["**/*.ts"]),
module_name = "@dataform/core",
deps = [
"//protos",
"@npm//@types/moo",
"@npm//@types/node",
"@npm//moo",
"@npm//protobufjs",
],
)
Это правило в Построить Файл рассказывает Bazel:
- Библиотека под названием
основной - Он должен включать все
.tsФайлы в этой папке - Имя модуля модуля (узел)
@ DataForm/Core - У него одна внутренняя зависимость
//Протос - У него есть несколько зависимостей NPM, как и
package.jsonфайл
Для создания этой библиотеки TS вы можете запустить:
bazel build core
Примечание: TS_LIBRARY. Правила и другие наборы, связанные с узлом, связанные с ним, не являются ядром для времени выполнения базеля, но импортируются из других мест. Вы можете прочитать больше о них здесь: https://github.com/bazelbuild/rules_nodejs .
Зависимости между пакетами
Если вы работали с NPM MonOrepo Monoorepo, вы, вероятно, использовали инструмент, похожий на Лерна Отказ
Lerna позволяет легко связать пакеты локально, чтобы вы могли испытывать изменения в нескольких пакетах NPM. Это также облегчает управление вариантом управления между ними. Мы хотим этого Отказ
Bazel строит и Ссылки Пакеты, не идущие рядом с фактическим пакетом NPM. В нашем @ DataForm/Core Пример выше, ts_library Правило зависит от //Протос который является просто еще один ts_library Правило Отказ
ts_library(
name = "protos",
srcs = glob(["index.ts"]),
module_name = "@dataform/protos",
deps = [
...
],
)
TS_LIBARY Правило делает немного магии, чтобы убедиться, что построенные пакеты доступны под module_name Приведен атрибут, который соответствует пакету NPM, они будут опубликованы.
Так в нашем @ DataForm/Core Пакет, мы можем импортировать из //Протос пакет, чей module_name это @ DataForm/Protos так:
import { dataform } from "@dataform/protos";
Когда мы публикуем NPM, эти импорт будут правильно разрешаться, поскольку имена модулей соответствуют имена пакетов.
Управление несколькими пакетами
Лерна также помогает вам управлять несколькими package.json Файлы, обновляя все версии вместе и публикуйте их. Мы хотели бы сделать то же самое в Базеле.
Генерировать package.json Файлы, которые мы построили небольшой инструмент В нашем монорепом Этот базель использует для генерации package.json Файлы с использованием слоев шаблонов JSON и строковые замены.
Для @ DataForm/Core Пакет, у нас есть Core.package.json Файл выглядит так:
{
"name": "@dataform/core",
"description": "Dataform core API.",
"main": "index.js",
"types": "index.d.ts",
"dependencies": {
"@dataform/protos": "$DF_VERSION",
"moo": "^0.5.0",
"protobufjs": "^6.8.8"
}
}
Любая дополнительная информация, лицензии, домашняя страница и т. Д. — унаследована от базы common.package.json Поэтому нам не нужно держать несколько файлов синхронизации.
Специальная строка $ Df_version Получает замену глобальной константой, определенным как часть системы сборки Bazel в версия.bzl Отказ
Создание пакетов NPM
Оценить эти шаблоны JSON, мы написали базель Макрос Чтобы вызвать наш инструмент выше, и мы вызови его в @ DataForm/Core Построить файл вроде:
load("//tools/npm:package.bzl", "dataform_npm_package")
dataform_npm_package(
name = "package",
package_layers = [
"//:common.package.json",
"core.package.json",
],
deps = [":core"],
)
Это Пользовательский базель макрос оба генерируют окончательный package.json Из двух шаблонов, перечисленных и создает папку «Выходную дистанцию» с компилируемым типографией, готов к публикации.
Чтобы увидеть вывод этого и окончательного сгенерированного package.json , вы можете запустить следующую команду:
bazel build core:package
Базель говорит нам, что он поставил пакет в папке Bazel-Bin/Core/Package с .js и .dts файлы, а также финал Package.json. (Это вроде как dist папка), которая готова опубликовать!
Примечание. Мы еще не полностью автоматизировали этот шаг, и все еще необходимо убедиться, что зависимости и имя пакета в СТРОИТЬ файл совпадает с теми Package.json. Шаблон, но это, безусловно, возможно автоматизировать это полностью.
Публикация пакетов NPM
Публикация легко на данный момент, и PRECLES_NODEJS Библиотеки имеют этот встроенный. Чтобы опубликовать пакет, который мы можем запустить:
bazel run //core:package.publish
У нас все еще есть сценарий Bash, чтобы сделать это для всех пакетов, но все, что он делает, это вызывает команды Bazel:
#!/bin/bash set -e # Test all the things. bazel test //... # Publish all the things. bazel run //api:package.publish bazel run //core:package.publish bazel run //cli:package.publish bazel run //crossdb:package.publish bazel run //protos:package.publish
Заключение
Это ни в коем случае не является полным решением, и в действительности потребуется, чтобы вы узнали довольно много о Bazel, чтобы он работал над своим собственным проектом. Для тех, кто пытается, надеюсь, наше репо Может служить хорошей ссылкой!
Несмотря на это, я надеюсь, что это показывает, что использование Bazel — отличное решение для управления сложными проектами и множеством пакетов узлов/Teadercript внутри одного репозитория. С несколькими небольшими дополнительными правилами Bazel вы можете построить Tymdercript Monorepo, который быстро освещается и будет масштабироваться, так как ваш проект делает.
Если вы нашли этот пост интересно и будут заинтересованы в Bazel Teamptry Starter Pack Reppo, протягиваясь, и мы посмотрим, что мы можем сделать!
Оригинал: «https://dev.to/lewish/building-a-typescript-monorepo-with-bazel-4o7n»