предисловие
Benpian - это команда студентов-инженеров, которые практикуют некоторые идеи и опыт вывода, хотя модуль es6 обеспечивает развязку кода, возможность уменьшить сложность программного обеспечения, но с соответствующими инженерными инструментами было относительно головной болью, npm npm в одиночку и встроенный - в пропускной способности канала не может удовлетворить крупномасштабная полностью модульная система, для которой мы немного попрактиковались и попробовали в этом отношении, кажется, результаты были хорошими, автор с точки зрения потребностей команды, стиль письма был бы более приземленный, читатели могут читать от своего имени.
Автор: Tax Friends Experience Technology Team - Цзян Хао
1. Предпосылки
В прошлом месяце с помощью прокси-доступа мы сначала попытались вынести [вызов клиентского метода] и [логику публичного меню] умной строки финансов и налогов в пакет npm для унифицированного управления. Принятое в то время техническое решение по зачистке общедоступной техники можно условно разделить на следующие пункты:
- Каждый общий технологический пакет существует как независимый пакет.
- Каждый пакет имеет общий технический репозиторий git (мусорщик).
- Каждый пакет публикует пакеты npm независимо.
- Каждый пакет управляет своей версией независимо.
- Несколько человек в каждой бизнес-группе совместно работают над разработкой и публикацией.
Однако в самом процессе разработки обнаружилось, что в каждом звене есть некоторые проблемы, как будто в первобытном обществе спецификации, рабочий процесс и производственные линии были неполными.
2. Сброс проблемы
2.1. Внутренний
- сотрудничество в области развития
- Управление филиалами, вытягивание, слияние спецификаций.
- Проблема с блокировкой устраняет трудности с синхронизацией.
- ...
- Управление внутренними зависимостями
- Внутренняя обработка зависимостей затруднительна, и версия обновляется вручную.
- Разные ветки имеют разные версии и не имеют возможности унифицированного управления зависимостями.
- ...
- Управление версиями
- Обновление версий вручную неэффективно, часто забывают обновить версии и подвержены ошибкам.
- Отсутствие унифицированных возможностей версии для управления.
- Обновление версии синхронизировано, и при наличии нескольких веток легко ошибиться.
- ...
- Управление выпуском
- Такие проблемы, как разрешения на выпуск и ветви выпуска, не сходятся, подвержены ошибкам, а результаты перекрывают друг друга.
- ...
- Внутренняя отладка
- Внутренняя отладка сложна.
- Связывание вручную неэффективно, а связывание в основном нереалистично, если пакеты взаимозависимы.
- ...
- Отсутствует производственная линия
2.2. Внешний
- Внешняя совместная отладка
- Внешняя совместная отладка крайне неудобна, что приводит к умножению версий.
- ...
- Управление журналом изменений
- Его отсутствие приводит к увеличению коммуникационных затрат, а извне не может воспринимать точку модификации после увеличения количества версий.
3. производственная линия
3.1. Аналогия с заводской производственной линией
Чтобы сначала сформировать абстрактную концепцию, мы будем абстрагировать производственную линию пакетов npm как заводскую производственную линию, чтобы помочь запомнить и понять.
Производственная линия пакетов npm похожа, и в ней также есть процесс создания -> разработка совместной отладки -> тестирование -> упаковка и сборка -> публикация. Наша первоначальная цель — построить полную производственную линию для мультипакетов npm.
3.2. ПОЧЕМУ монорепозиторий
Концепция монорепозитория в просторечии — это способ управления несколькими пакетами npm в одном репозитории кода (в отличие от мультирепозитория, который относится к нескольким пакетам и нескольким репозиториям).
В настоящее время многие популярные проекты с открытым исходным кодом используют монорепозиторий для управления кодом, например: babel, Vue3.0.
- Что нам нужно?
Прежде всего, ясно, что одним из направлений управления нашим проектом должно быть постоянное разделение общедоступных технологий и разделение их на более мелкие модули для поддержки более гибкого бизнеса и повторного использования Таким образом, количество пакетов npm должно быстро расти. По мере роста взаимозависимость усложняется. Так что для растущего количества npm-пакетов нам срочно нужно решение по управлению пакетами, идеальное, скоординированное, удобное для совместной работы и максимально охватывающее весь процесс. Это то, что нам нужно.
Управление несколькими складами, естественно, проблематично. Будь то совместная работа нескольких человек или независимая разработка, сложность задач с несколькими складами должна возрастать в геометрической прогрессии.
- Что решает монорепозиторий?
И монорепозиторий призван решить эти проблемы.
«Любая проблема в информатике может быть решена с помощью дополнительного уровня косвенности». «Все проблемы в вычислениях можно решить, добавив слой» — IT-пословица.
Объединяя все пакеты в пакеты и управляя зависимостями, сборкой, разработкой/отладкой, тестированием, управлением версиями и выпуском каждого пакета унифицированным образом на верхнем уровне, он обеспечивает более элегантное решение для управления несколькими пакетами и совместной работы.
4. Детали плана
Целью предварительного плана производственной линии является его улучшение и реализация.
Рабочие пространства Lerna и yarn являются распространенными инструментами управления монорепозиториями на рынке.Поскольку рабочие пространства lerna и yarn имеют много функциональных перекрытий, мы планируем принять предложения, представленные на официальном сайте пряжи (цель рабочих пространств пряжи — предоставить лучшие решения для зависимостей, Не будет предоставлять некоторые сложные функции управления, такие как lerna)
- Используйте рабочие области пряжи исключительно для работы с зависимостями.
- Используйте lerna для решения проблемы координации управления пакетами.
Также на ранней стадии будут некоторые вещи, которые не могут быть решены с помощью инструментов, здесь мы рассматриваем [норма/ограничение + проверка], чтобы обеспечить это.
4.1 Базовая структура каталогов
├── README.md
├── lerna.json // 全局的lerna配置文件
├── package.json // 全局package.json,主要用来配置yarn workspaces和全局依赖、全局scripts
├── packages // 各个npm包放在这个文件夹下
│ ├── itr-menu // package A
│ │ ├── README.md
│ │ ├── dist
│ │ ├── lib
│ │ ├── package.json // package A的package.json,配置自己的依赖、scripts、描述。
│ └── scavenger-client // package B
│ ├── README.md
│ ├── dist
│ ├── index.js
│ ├── package.json // package B的package.json
│ ├── src
└── yarn.lock
4.2. Строительство окружающей среды
Создание среды здесь в основном относится к установке lerna, вы можете выбрать глобальную установку lerna:
npm i lerna -g
Вы также можете использовать lerna в проекте и перейти к общему репозиторию для установки зависимостей.
Если основной проект использует lerna впервые, вам необходимо использовать lerna для инициализации основного проекта:
lerna init
Два файла, lerna.json и package.json, генерируются в корневом каталоге проекта для описания зависимостей и конфигураций lerna.Общие элементы конфигурации будут подробно представлены далее, но не будут здесь подробно.
Официальная документация -элемент конфигурации lerna.json
4.3, создайте новый пакет
Использовать lerna для создания нового пакета очень удобно, просто нужно находиться в корневом каталоге основного проекта, через командную строку:
lerna create package-name
Затем введите информацию описания пакета, когда будет предложено завершить создание.
В будущем его можно рассматривать как совместное использование со строительными лесами.
4.4 Управление зависимостями
По содержанию предыдущего обзора, по сути, для управления зависимостями мы сталкиваемся со следующими проблемами:
- Подпакеты зависят от объема пакета: по мере увеличения количества пакетов объем пакета увеличивается в геометрической прогрессии, а время установки зависимостей увеличивается в геометрической прогрессии.
- Взаимозависимость между вложенными пакетами: по мере увеличения количества пакетов ручные операции связывания и версии становятся обременительнее во время разработки и совместной отладки.
- Операции зависимости пакета подпакета сложны: по мере увеличения количества пакетов операции установки и очистки зависимостей усложняются.
Видно, что нам срочно нужен инструмент согласования и автоматического управления зависимостями для решения вышеуказанных задач. Возможности рабочей области пряжи следующие:
- Благодаря анализу зависимостей и алгоритму продвижения зависимостей рабочая область пряжи обновляет общие и часто используемые зависимости каждого пакета до основного проекта, чтобы решить проблемы размера пакета и времени установки.
- Рабочее пространство пряжи проанализирует внутренние зависимости между пакетами в соответствии с топологической последовательностью и автоматически решит проблему внутренней взаимозависимости через аналогичную мягкую цепочку (ссылку).
- Рабочая область пряжи может управлять установкой, очисткой, просмотром зависимостей и другими операциями, поскольку унифицированное управление осуществляется с помощью нескольких простых команд в рамках основного проекта, что является простым и быстрым.
Сама Lerna также способна управлять зависимостями, но рабочие области пряжи имеют лучший анализ зависимостей и алгоритмы подъема («Анализ алгоритма подъема рабочего пространства Lerna и Yarn»), поэтому здесь мы решили использовать рабочие области пряжи для управления нашими зависимостями.
4.4.1 Специальное использование и общие команды
- Во-первых, вам нужно открыть воркспейсы пряжи в основном проекте, способ открытия очень прост, вам нужно только открыть его в файле package.json основного проекта:
{
"name": "root",
"private": true, // 标明是主工程,不会被发布
"devDependencies": {
"lerna": "^3.22.1"
},
"workspaces": [ // 开启workspaces功能,并且声明子package(可以手动指定package,也可以通配符指定package路径)
"packages/*"
]
}
После инициализации основного проекта с помощью lerna рабочие области пряжи будут автоматически открыты.
После простого открытия подпакеты могут начать управлять зависимостями через рабочее пространство пряжи без каких-либо изменений.
- Установить зависимости
Чтобы установить зависимости, вам нужно только выполнить установку пряжи (или прямую пряжу) в корневом каталоге основного проекта, и рабочая область пряжи автоматически обработает анализ зависимостей, продвижение, установку и мягкую цепочку.
yarn install
- Добавить | Удалить зависимости
Добавление | Удаление зависимостей обычно делится на три сценария:
- Добавить зависимости к пакету
// 新增-第三方
yarn workspace package-name add react
// 新增-内部
yarn workspace packageA add packageB
// 删除
yarn workspace package-name remove react
- Добавить зависимости ко всем пакетам
// 新增
yarn workspaces add react
// 删除
yarn workspaces remove react
- Добавьте зависимости к основному проекту
// 新增
yarn add -W -D react
// 删除
yarn remove -W -D react
- Просмотр внутренних зависимостей
yarn workspaces info
Выведите информацию о зависимостях каждого пакета в текущей рабочей области в древовидной структуре (требуется версия пряжи 1.13 или выше), например:
{
"@itr/itr-menu": {
"location": "packages/itr-menu",
"workspaceDependencies": [
"scavenger-client"
],
"mismatchedWorkspaceDependencies": []
},
"scavenger-client": {
"location": "packages/scavenger-client",
"workspaceDependencies": [],
"mismatchedWorkspaceDependencies": []
},
"test-package": {
"location": "packages/test-package",
"workspaceDependencies": [],
"mismatchedWorkspaceDependencies": []
}
}
4.5, строительство проекта
Подпакеты будут иметь свои собственные команды сборки.Унифицируйте команды сборки пакетов для каждого пакета в соответствии со спецификациями команды.Используя lerna, вы можете собрать все подпакеты одним щелчком мыши. Кроме того, если между подпакетами есть взаимная зависимость (например, пакет B может быть собран только после того, как будет собран пакет A, иначе произойдет ошибка), то lerna также поддерживает сборку по правилам топологической сортировки. Конкретные команды следующие:
lerna run --stream --sort build
Когда есть необходимость в самостоятельной сборке, lerna также поддерживает запуск скриптовой команды пакета в одиночку.
lerna run --scope package-name build
4.7 Релиз проекта
Когда разработка и тестирование завершены, он официально переходит в стадию релиза, но до того, как он будет официально выпущен в npm, нужно решить еще несколько вещей:
version bump -> changelog -> git release -> npm publish
**
4.7.1, бамп версии
Обновление версии — одна из наиболее очевидных проблем, с которыми мы столкнулись ранее.Вручную изменить номер версии проблематично, и легко допустить ошибку, если пакетов слишком много.Если есть взаимозависимые пакеты, это еще больший кошмар.
В ответ на эти проблемы, lerna предоставляет нам отличное решение, которое поддерживает управление обновлениями номеров версий всех пакетов одним щелчком мыши, включая внутренние взаимозависимые пакеты, которые также можно обновлять одновременно одним щелчком мыши. Он даже включает универсальный сервис, включая отправку git и построение тегов версии. Давайте подробно представим механизм изменения версии lerna.
Основная команда:
lerna version
Перед обновлением версии эта команда автоматически сделает некоторые предварительные выводы для обновления версии:
- Если в локальном коде есть незафиксированные изменения, вы не сможете обновить версию, пока не откатите изменения или не зафиксируете изменения.
- Если код пакета не имеет изменений по сравнению с кодом последней выпущенной версии, обновление версии немодифицированного пакета производиться не будет.
В случае принятия этих предварительных решений может быть выполнено обновление версии.
lerna version --conventional-commits
Параметр --conventional-commits может поддерживать автоматическое обновление номера версии непосредственно в соответствии с нашей записью отправки git (при условии, что спецификация [условная отправка] удовлетворена):
- существуетfeatКоммит: необходимо обновить минорную версию
- существуетfixCommit: необходимо обновить версию патча
- существуетBREAKING CHANGEОтправить: нужно обновить большую версию
После успешного обновления версии lerna будет использовать chore(release): publish, чтобы отправить коммит и отправить его в git в качестве записи фиксации выпуска версии, и каждый пакет будет автоматически генерировать тег текущей версии, который зарезервирован. для отката версии.
Если вы не хотите автоматически генерировать номер версии, вы можете не указывать параметр --conventional-commits, а затем вручную указать версию каждого пакета,Но не рекомендуется.
4.7.2, журнал изменений
На самом деле, после команды version на предыдущем шаге, lerna автоматически сгенерировала файл CHANGELOG.md для каждого пакета в соответствии с записью отправки git.Конечно, он также основан на [обычной отправке].
Следует отметить, что необходимо использовать отправку области при отправке, чтобы разные пакеты отправлялись в соответствующих файлах журнала изменений при окончательном создании журнала изменений, например:
feat(scavenger-client): xxxxx
4.7.3, опубликовать
Далее последний шаг — публикация в npm. По сути, мы уже проделали подготовительную работу, осталась последняя строчка команды, можем отправить пакет в npm по сгенерированному версией тегу:
lerna publish from-git
Перед выпуском версии рекомендуется вернуться к мастеру и объединить его.
4.8 Совместная отладка
4.8.1 Местный
Для совместной отладки локального кода рекомендуется использовать npm-ссылку на локальные результаты, конкретный метод следующий:
- cd в каталог packageA и выполните:
npm link
- cd к проекту, который зависит от packageA и выполнить
npm link packageA
затем сделано. Это настолько просто, что вы можете напрямую отлаживать код локального packageA в локальном проекте, не выпуская новую версию.
V. Резюме
На данный момент процесс от создания упаковки до релиза завершен, а производственная линия также имеет предварительный вид и функции. Но последующие действия все еще нуждаются в улучшении, включая процесс тестирования, внешнюю совместную отладку, открытие с помощью ci/cd, автоматизацию процесса и т. д. Строго говоря, текущие результаты — это не рабочий процесс, производственная линия (Черт! заглавная вечеринка) , но может привести нас к переходу от чисто ручного труда в «первобытном обществе» к эпохе «индустрии 1.0» парового двигателя вместо ручного механического производства. В будущем предстоит еще долгий путь, и Эпохи 2.0 и 3.0 должны продолжать массовое производство, автоматизированную, современную «производственную линию». Я верю, что благодаря постоянному развитию и эволюции нашей команды, следующая «промышленная революция» скоро наступит.
позже
В будущем мы поделимся опытом и знаниями нашей команды в области инженерной практики.Если вы сосредоточены на инженерной практике и готовы думать и решать различные сложные инженерные проблемы, вы можете следовать за нами и учиться вместе.