Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
Пожалуй, все, кто имел дело с развитием семейства сайтов, сталкивались с проблемой поддержания единого вида компонентов. Когда счет сервисов идет на десятки и сотни, когда над ними работает все больше независимых друг от друга команд, рассинхрон в дизайне и коде появляется обязательно. Мы попробовали справиться с этим с помощью единой базы компонентов. В серии постов я расскажу о нашем опыте разработки UI-кита, удобного как для разработчиков, так и для дизайнеров, подходящего для разных фреймворков и не слишком утяжеляющего сервисы. В первой части под катом рассказываю, как мы выбирали фреймфорки.
В монолитной системе работа с дизайном происходит централизованно, например, с помощью выделения локальных компонентов. При движении к микросервисной архитектуре неизбежно возникают проблемы с соответствием элементов интерфейса. Мы столкнулись с этим, когда вынесли часть функционала из монолита и потребовалось обеспечить единообразие и синхронное изменение элементов в случае обновления дизайна.
Давайте предположим, что нам нужно создать новый компонент, который будет отображать аватар пользователя. Он должен появиться на страницах абсолютно разных сервисов, которые разрабатываются разными командами. При классическом подходе мы бы сделали аватар в каждом сервисе независимо. И в тот момент, когда дизайнеры решили бы, что все аватарки должны иметь фиолетовую кайму, мы бы получили проблему. Переход на микрофронтенды сделал бы все еще хуже — пользователи могли бы увидеть по-разному оформленные аватарки на одной странице.
Мы начали тратить слишком много ресурсов на разработку и поддержку однотипных элементов. Общая база, которую могли бы использовать все команды в своих проектах, позволила бы нам увеличить скорость работы, отображать нужные версии элементов, быстро их подгружать и менять, при этом быть уверенными, что каждый компонент соответствует дизайн-системе. Так мы решили разработать UI-кит.
И для разработчика, и для дизайнера
Создавая UI-кит, мы постарались сделать так, чтобы дизайнер мог участвовать в развитии интерфейса, не привлекая разработчиков. Он выбирает размер, цвет, шрифт, поведение компонентов прямо из Figma — для этого там есть отдельная доска, на которой задаются дизайн-токены. Например, дизайнер может обозначить основной цвет (color-primary
) как фиолетовый, тогда для визуальных компонентов будет использоваться именно он.
Разработчики применяют UI-кит при создании сервисов. Теперь не нужно писать компоненты заново — достаточно обратиться к общей библиотеке.
Выбираем основу библиотеки
На сегодняшний день мы развиваем наш UI-кит на базе кросс-платформенного компилятора Stencil, используем частичную автоматизацию обновления компонентов и подтягиваем нужные параметры дизайна через токены из Figma. Это совершенно осознанное решение, так как у нас был ряд требований к фреймворку, на котором мы собирались формировать единую базу.
Нам нужна была максимально стабильная библиотека, которая решала бы проблемы с дизайном и не создавала новые. Поэтому мы специально выбирали инструмент с хорошим функционалом и качественной поддержкой, чтобы не пришлось допиливать его самостоятельно. По крайней мере, не сразу и не по всем фронтам.
Также мы хотели оставить себе пространство для маневра, чтобы не быть привязанными к определенному фреймворку. Отчасти потому, что несколько решений уже развивались не на рекомендуемом в компании стеке (React). Но в большей степени из-за нежелания безусловно завязываться на одной технологии. Учитывая скорость развития отрасли, мы должны были обеспечить командам возможность экспериментировать с технологиями без отказа от базы готовых UI-элементов.
Библиотек и фреймворков для создания веб-компонентов много. Например, ресурс WebComponents.dev, кроме предоставления исчерпывающего списка вариантов, обновляет их и информацию об их характеристиках. Мы составили свой топ-3: связку lit-element + lit-html и фреймворки Stencil, Hybrids — выделили наиболее значимые критерии и сравнили по ним. На момент выбора — это было в начале июня 2020 года — получили такую картину:
Критерии | Фреймворк/библиотека | ||
lit-element + lit-html | Stencil | Hybrids | |
JavaScript ES3+ | + | + (при использовании полифиллов) | + |
JavaScript ES6+ | + | + | - |
TypeScript | + | + | + |
JSX | + | + | + |
Выгрузка для React | - | + (при использовании плагина) | - |
Выгрузка для Vue | - | + (при использовании плагина) | - |
Поддержка работы без фреймворка | + | + | + |
Поддержка IE11 | + | + (при использовании полифиллов) | - |
Поддержка современных браузеров | + | + | + |
Поддержка плагинов / возможности расширения | - | + | - |
CSR | + | + | + |
SSR | + (при использовании доп. библиотеки) | + | - |
Подключение ассетов и CSS как отдельных файлов | - | + | - |
Хорошая документация | + | + | + |
Развитое комьюнити | + | + | + |
Что за выгрузка в React/Vue?
Возможно критерии «Выгрузка для React» и «Выгрузка для Vue» вам покажутся странными. Но мы искали инструмент, который сможет дать возможность работать с веб-компонентами как с обычными React и Vue компонентами.
На первый взгляд, lit-element + lit-html и Stencil показались почти равноценными. Первые не поддерживали плагины или не давали возможности расширения, соответственно не решали наш вопрос с выгрузкой, не поддерживали подключения ассетов и CSS как отдельных файлов, а со вторым на помощь пришли плагины. Для большей ясности мы ввели коэффициенты для каждого критерия и остановились на Stencil.
Если у вас похожий стек, можете посмотреть нашу таблицу.
Еще один важный фактор успеха — это размер бандла. Ведь библиотека, которую мы подключаем в проект, тянет за собой определенное количество кода — для браузера и для внутренних функций.
Когда мы выбирали инструменты, оценивали, насколько изменится размер бандла сайта и на React, и на Vue. Сначала все было не очень хорошо, потому что демосайт на React весил без библиотеки 2,5 Мбайт, а с библиотекой — 5 Мбайт. Бандл оказался таким большим потому, что по умолчанию Stencil предоставляет библиотеку с полифилами с поддержкой старых браузеров. Чтобы уменьшить размер бандла, мы использовали решение для выгрузки компонентов в виде отдельных файлов, с которыми очень хорошо работают фреймворки. Также мы отдельно вынесли шрифты и подключаем их по URL — так мы добились, чтобы с библиотекой на Stencil сайт весил 3 Мбайт. Это хорошо, хотя уже сейчас понятно, что можно еще поработать над размером дополнительных компонентов.
От Figma до готового компонента
Когда что-то меняется на доске в Figma — дизайнеры добавляют новый компонент или корректируют старый — изменения попадают в общую базу. Например, в случае смены цвета или шрифта отправляется автоматическое уведомление мейнтейнерам, и они обновляют соответствующие элементы библиотеки. Эта часть работы происходит вручную — мы пока не стремимся к полной автоматизации, а то пришлось бы создавать нейронные сети для генерации кода. Впрочем, в наше время это вполне можно сделать, и наверняка кто-то уже пользуется подобными подходами.
Чтобы уменьшить влияние библиотеки на размер бандлов сервисов и по ряду других причин, мы решили распространять бандл библиотеки независимо от приложений. При этом схема подключения скрыта от конечного пользователя, поэтому, если мы решим в будущем изменить ее, это не потребует изменений в коде сервисов.
С другой стороны, нужно было разобраться с появлением одного компонента интерфейса в разных микрофронтендах на одной странице. Само по себе это не проблема, но давайте вернемся к примеру с аватаркой. Что произойдет, если в каждом из сервисов библиотека компонентов и, следовательно, аватарка будут разных версий? В текущей реализации мы подключим библиотеку только один раз, если версии совместимы, и покажем пользователю цельный и непротиворечивый интерфейс.
Для корректной работы такой схемы мы придерживаемся правил семантического версионирования и используем конвенцию именования коммитов для автоматизации создания версий.
Кстати, процесс окончательного релиза библиотеки мы тоже начали автоматизировать. Сначала выпускается релиз-кандидат (RC), после этого изменения проверяются на предмет совместимости (вдруг дизайнер что-то перепутал и отображение сломалось), и если все окей, то новшества вносятся в библиотеку, выпускается новая стабильная версия.
Для презентации UI-кита мы используем Storybook. Бандлы выкладываются сначала на внутренний ресурс. Дизайнер или менеджер может зайти, «пощупать» какой-то компонент, изучить особенности работы, почитать описания настроек. Например, можно сделать кнопку активной или неактивной и посмотреть, как это выглядит, еще до публикации бандла. Во второй вкладке таблицы вы найдете сравнение интерфейсов для UI-кита.
Мы работаем над тем, чтобы сделать триггеры и автоматизировать все процессы публикации. Но уже сейчас использование одной библиотеки гарантирует соответствие сайта концепции дизайна и единому стилю и позволяет разработчикам не верстать стандартные элементы каждый раз заново. Кстати, в качестве первого опыта мы уже запустили часть сайта в новой парадигме.
Расскажите в комментариях, используете ли вы в работе UI-киты. Может быть, у вас уже есть лайфхаки по дальнейшей оптимизации процессов дизайна и переходу на микрофронтенды? Приходилось ли вам более глубоко автоматизировать обновление компонентов в библиотеках? Насколько увеличивается размер бандла из-за использования общего UI-кита в вашем случае и удалось ли вам его оптимизировать? Интересно было бы узнать о вашем опыте.