Большинство компонентов версионируются как часть проекта (например, component-library
), что противоречит концепции создания модульных UI-приложений. Например, чтобы использовать слайдер-компонент, нужно внедрить в приложение полную библиотеку с единой версией, которой должен соответствовать каждый компонент.
Версионирование отдельных компонентов с использованием SemVer обеспечивает детальный контроль над составом UI-приложений. Разработчики могут использовать общие компоненты, а также получают возможность обновлять части пользовательского интерфейса без конфликтов, сохраняя при этом независимость команды.
Создание единой версии для библиотеки компонентов является распространенной практикой.
library 1.0.0
├─ visual style
└─ components
├─ button
├─ button group
├─ card
├─ checkbox
├─ radio button
└─ ...
Большинство библиотек представляют собой единый версионный пакет:
npm install @material-ui/coreЭта практика затрудняет внедрение компонентов, вынуждая разработчиков связывать свою разработку с библиотекой, согласовывать все версии и обновлять все компоненты на каждой из них.
Есть лучший вариант: версионирование и распределение отдельных компонентов по правилам SemVer. Они также используются в инструментах проектирования и предоставляют возможность согласовывать дизайн и код каждого компонента к единой версии.
library
├─ visual style
└─ components
├─ button 5.3.1
├─ button group 2.1.0
├─ card 3.7.6
├─ checkbox 3.1.0
├─ radio button 1.1.0
└─ ...
Версионирование компонентов предоставляет множество преимуществ как для разработчиков, так и для пользователей: первые могут непрерывно передавать обновления для определенных компонентов, а вторые получают эти обновления без возникновения конфликтов.
Пользователи могут получать обновления только тех компонентов, которые они используют. Правила SemVer отлично подходят для связи различных обновлений по старшим, младшим и патч-версиям.
Такие инструменты, как Bit, упрощают этот процесс как для разработчиков, так и для пользователей, предоставляя такие функции, как автоматическое создание тегов для зависимых компонентов при внесении изменений.
Разработка внутренних компонентов и одновременное добавление сторонней библиотеки создают конфликты версий зависимостей.
Например, в приложении находится внутренний компонент «Scroller» с зависимостью «Scroll-JS» в версии 3.0.1
. Сторонняя библиотека добавляет в приложение компонент «Button». Однако она также содержит компонент «Scroller», зависимый от «Scroll-JS» в версии 2.0.2
. В данном случае могут возникнуть конфликты.
Тем не менее, если приложение принимает из библиотеки только компонент «Button», то конфликт полностью устраняется.
Избыточный конфликт устранен!Библиотеки компонентов с единой версией не позволяют распространителю выпускать постепенные обновления для каждого компонента. Например, новая старшая версия «Slider» не может быть выпущена до следующей старшей версии библиотеки. То же самое касается младших и патч-версий, которые обновляют версию в соответствии с библиотекой.
Версионирование отдельных компонентов предоставляет возможность непрерывного релиза обновлений и безопасного выполнения отката или внесения исправлений. Таким образом, версию «Slider» можно повысить с 1.0.0
до 1.0.1
, не дожидаясь следующего релиза библиотеки.
Компоненты SemVer можно использовать для внедрения набора общих компонентов и объединения их со специальными версиями.
Например, можно безконфликтно внедрить набор общих компонентов с версией 1.0.0
и обновить только «Slider» с патчем до версии 1.0.1
. В крайних случаях возможно даже представить различные версии компонента на одной странице.
С помощью bit import
это можно выполнить локально прямо в приложении. Поскольку HTML-разметка, стиль и сценарий инкапсулированы в компоненте, он не будет конфликтовать с другими типами компонентов.
Когда команда принимает библиотеку с единой версией, она связывает разработку своего приложения с разработкой библиотеки, что предполагает управление roadmap’ом продукта и свободу предоставления обновлений.
Версионирование компонентов «узаконивает» внедрение и модификацию компонентов, а такие инструменты, как Bit, «легализуют» разработку общих компонентов. С помощью команды bit import
разработчики, использующие общие компоненты, могут изменять и обновлять любой из них, а также смешивать версии и добавлять собственные компоненты и версии в коллективный пул.
Версионирование отдельных компонентов ускоряет разработку и повышает производительность созданного приложения.
Производительность. При добавлении и использовании лишь необходимых компонентов уменьшается размер пакета приложения. В результате браузер анализирует меньшее количество кода, что сокращает время выполнения.
Стабильность. Компоненты SemVer повышают стабильность благодаря безопасному внедрению постепенных обновлений в определенные UI. При обновлении отдельных компонентов также упрощается использование модульных тестов. Bit тестирует и собирает каждую версию в отдельности, прежде чем внедрить ее в приложение.
Скорость разработки. Использование общих компонентов повышает скорость работы команды. При необходимости обновление можно как запросить, так и выполнить самостоятельно (т.е. bit import
). В результате экономится время на разработку новых функций и на обслуживание текущей базы кода.
Bit — это инструмент, выполняющий тегирование различных компонентов на основе SemVer внутри одного проекта (библиотеки или приложения).
С помощью команды bit add
Bit отслеживает компоненты в репозитории, анализирует каждый из них и выполняет поиск всех его файлов и зависимостей. Он автоматизирует процесс упаковки компонента, генерирует файл package.json
и изолирует его встроенную/тестовую среду. В результате каждый компонент может быть версионирован, собран, протестирован и экспортирован по отдельности.
Команда bit tag
тегирует компонент с помощью SemVer, а затем Bit подсказывает, какие компоненты также необходимо обновить, и автоматически тегирует их.
Версионированные компоненты можно экспортировать и распространять между командами и проектами. После обновления до новой версии компонент может независимо обновляться различными приложениями по правилам SemVer.
Bit также помогает сохранить независимость каждой команды, предоставляя возможность импортировать (bit import
) общие компоненты в собственный проект.
В этом примере показан компонент hello/world
. Предположим, что он уже изолирован и добавлен в Bit (с помощью bit add
). В таком случае ему уже предоставлены независимые конфигурации сборки и тестирования (Bit также автоматизирует этот процесс). С этого момента компонент становится отдельной единицей, находящейся внутри проекта.
При запуске bit status
получаем следующий вывод:
$ bit status
new components
> hello/world... ok
Чтобы тегировать компонент hello/world
, используем bit tag
:
$ bit tag hello/world
1 components tagged | 1 added, 0 changed, 0 auto-tagged
added components: hello/[email protected]
Вы также можете тегировать все новые или модифицированные компоненты в области видимости с помощью --all
:
$ bit status
new components
> hello/world... ok
> ui/button... ok
modified components
> string/pad-left... ok
$ bit tag --all
3 components tagged | 2 added, 1 changed, 0 auto-tagged
added components: hello/[email protected], ui/[email protected]
changed components: string/[email protected]
С помощью опции --scope
можно тегировать все компоненты, находящиеся в локальной области видимости. Bit согласовывает все компоненты по указанному номеру версии:
Bit может устанавливать определенную версию при тегировании компонента:
$ bit tag hello/world 1.0.0
1 components tagged | 1 added, 0 changed, 0 auto-tagged
added components: hello/[email protected]
Bit также может тегировать все компоненты с помощью указанного инкремента SemVer. Bit поддерживает такие инкременты, как patch
, minor
и major
:
bit tag --all --major # Инкрементирование всех измененных и новых компонентов с помощью старшей версии.
bit tag --all --minor # Инкрементирование всех измененных и новых компонентов с помощью младшей версии.
bit tag --scope --patch # Инкрементирование всех компонентов с помощью патч-версии.
bit tag --scope --patch # Инкрементирование всех компонентов в рабочем пространстве с помощью патч-версии.
После тегирования компоненты можно экспортировать с помощью bit export
в удаленную коллекцию.
Bit управляет зависимостями благодаря сохранению полного графа зависимостей компонентов. После тегирования Bit также помечает другие компоненты, находящиеся в локальной области видимости и зависящие от него.
Зависимые компоненты всегда помечаются patch
версией независимо от основного инкремента компонента.
Допустим, у нас есть 2 компонента: navbar
и main-menu
. navbar
импортирует компонент mainmenu
следующим образом:
Отслеживаем компоненты в bit с помощью команды bit add
. bit status
отображает добавленные компоненты:
$bit status
new components
(use "bit tag --all [version]" to lock a version with all your changes)
> main-menu ... ok
> navbar ... ok
Тегируем оба компонента до версии 0.0.1
:
$bit tag --all
2 component(s) tagged
(use "bit export [collection]" to push these components to a remote")
(use "bit untag" to unstage versions)
new components
(first version for components)
> [email protected]
> [email protected]
Снова запускаем bit status
, который теперь отображает тегированные компоненты:
$bit status
staged components
(use "bit export <remote_scope> to push these components to a remote scope")
> main-menu. versions: 0.0.1 ... ok
> navbar. versions: 0.0.1 ... ok
Теперь внесем некоторые изменения в код main-menu
, который является зависимостью navbar
, и снова запускаем bit status
:
$bit status
modified components
(use "bit tag --all [version]" to lock a version with all your changes)
(use "bit diff" to compare changes)
> main-menu ... ok
staged components
(use "bit export <remote_scope> to push these components to a remote scope")
> main-menu. versions: 0.0.1 ... ok
> navbar. versions: 0.0.1 ... ok
components pending to be tagged automatically (when their dependencies are tagged)
> navbar ... ok
Мы видим, что main-menu
изменено, а navbar
также тегируется, поскольку его зависимость была изменена.
Теперь тегируем main-menu
. В результате мы видим, что navbar
также тегирован:
$bit tag main-menu
2 component(s) tagged
(use "bit export [collection]" to push these components to a remote")
(use "bit untag" to unstage versions)
changed components
(components that got a version bump)
> [email protected]
auto-tagged dependents: [email protected]
После этого все тегированные компоненты, включая зависимости, переходят в состояние staged
. Для проверки можно запустить bit status
.
Версионирование отдельных компонентов — это важнейший шаг на пути к сохранению независимости команды, безопасному созданию и развертыванию частей приложения, а также совместному использованию и синхронизации компонентов в различных приложениях.
Перевод статьи Jonathan Saring: The Case for Versioning Independent UI Components
Комментарии