Привет!
Саша Инкин и я регулярно пишем на Хабр статьи по Angular. Почти все они основаны на нашем опыте разработки большой библиотеки компонентов.
Эту библиотеку мы развиваем, перерабатываем и дополняем уже несколько лет, а свои идеи проверяем на нескольких десятках проектов Тинькофф Бизнеса и внутренних систем компании. Мы рады сообщить: выложили нашу библиотеку в открытый доступ!
В этой статье хочу описать основные концепции и практики, на которых строится библиотека, а также рассказать, почему ее стоит внедрить как в новые проекты, так и в уже готовые — с иными компонентами или UI Kit’ами.
Как развивался наш UI Kit и как он организован
Если вам интересно узнать, зачем нам понадобилась отдельная библиотека компонентов и как она исторически развивалась, то сначала рекомендую прочитать крутейшую статью Юли Царевой — «Как организовать работу над библиотекой общих компонентов».
В той статье речь шла как раз про нашу библиотеку, но годовалой давности. С тех пор у нас произошло одно фундаментальное изменение: пакеты проекта стали делиться на две части — проприетарную и публичную.
В проприетарной содержатся более верхнеуровневые блоки интерфейса, которые нужны нескольким продуктовым командам. Такие компоненты завязаны на дизайн проектов и не имеют особого смысла вне контекста приложения нашего интернет-банка для юрлиц.
В публичной же части находятся как базовые компоненты вроде кнопки, календаря или поля ввода текста, так и более сложные вроде поля выбора диапазона двух дат, мультиселекта или целого WYSIWYG-редактора.
Эта часть обзавелась собственным дизайном и полной независимостью от контекста, а недавно оправдала свое название переездом в опенсорс. Давайте познакомимся с нашим UI Kit поближе!
Полностью модульный
Начнем с того, как организован проект. Taiga UI состоит из нескольких слоев, которые являются отдельными пакетами.
@taiga-ui/cdk
Фундаментальный пакет. Представляет собой набор директив, сервисов, токенов, абстрактных классов и утилит для абстрагирования и упрощения работы с Angular. Может быть использован как дополнительный мультитул с удобствами для вашего Angular-приложения любой сложности, а может и стать основой для построения собственного кита.
Пример сущностей:
TuiDestroyService для избавления от постоянного создания сабжектов destroy$ в компонентах.
TuiFilterPipe и TuiMapperPipe для обработки значений в шаблонах без лишних вызовов ChangeDetection.
Декоратор tuiPure для мемоизации значений геттеров и методов класса.
@taiga-ui/core
Пакет с базовыми компонентами для построения интерфейсов, а также с инструментами для основы веб-приложения. Это инструменты вроде рутового компонента, порталов для диалогов и выпадашек, настройки темизации и анимаций. Core задает вектор остальным пакетам c UI-элементами. На этом уровне появляется дизайн и все общие стили лежат тут.
@taiga-ui/kit
Самый большой пакет, в нем содержится основная часть компонентов, из которых можно собрать практически любой общий интерфейс. Здесь лежат как простые компоненты вроде аватарки, тега или тоггла, так и составные. Например, поле ввода даты состоит из трех базовых компонентов: поля ввода с ограничением формата, выпадашки и календаря.
@taiga-ui/addon-*
Ряд тематических пакетов, которые основаны на первых трех. Например, есть пакет charts для графиков, commerce для работы с валютами, деньгами и вводом карт или даже отдельный пакет doc для построения собственной витрины аналогично нашей (ссылка на нее будет дальше ?).
Получается вот такая иерархия, при которой пакеты более высокого уровня строятся на базовых пакетах:
Вопрос: зачем тянуть в зависимости несколько пакетов, если я хочу лишь пару компонентов? Сколько они весят?
Несколько месяцев назад мы перешли от концепции единых точек входа в каждый пакет к полной разбивке всех пакетов на Secondary Entry Points. Чтобы сохранить удобный и привычный контракт импортов, мы устроили все пакеты по уникальной схеме, когда каждый последующий уровень вложенности является Secondary-поинтом к текущему, но Primary — к сущностям своего содержимого.
Теперь все наши пакеты дают возможность импортировать сущности как из Primary точки входа, так и из любого уровня вложенности:
Причем первый вариант импорта достаточен, дополнительная вложенность автоматически разрешается на этапе сборки.
Такой подход к работе с Secondary Entry Points дает целый ряд плюсов в организации библиотек:
Бандл-приложений меньше, библиотека становится максимально tree shakable.
Любые циклические зависимости отлавливаются на этапе сборки.
Больше структурности в проекте, нет лишних связей между сущностями.
Фактически при импорте любой сущности нашей библиотеки к вам в бандл попадет только она сама и только необходимые ей сущности из пакетов выше. Код не дублируется и не тянет за собой веретено зависимостей. Если вам нужна одна функция из cdk — можете смело подключать пакет, ваш бандл увеличится ровно на размер кода этой функции.
Кастомизируемый
Все стили и цвета задаются через CSS custom properties. Это позволяет легко собирать кастомные темы или даже подменять их в приложении на ходу.
Пока у нас доступна к выбору только одна основная тема, но мы планируем выпустить еще несколько стандартных и необычных вариантов.
Если хочется хитрее кастомизировать конкретный компонент, для этого тоже предусмотрены отдельные рычаги. Теоретически за пару часов вы можете переделать наш кит под свою дизайн-систему и спокойно использовать, а мы со своей стороны не будем нарушать контракт переменных, чтобы не поломать верстку.
Агностичный
Мы стараемся делать наши компоненты так, чтобы любой разработчик мог быстро подстроить их под свой конкретный специфический кейс.
Мы не завязываемся на интерфейсы, не ограничиваем визуальное отображение и думаем о том, как сделать компонент максимально гибким в использовании, а не продумываем все возможные юзкейсы. Подробнее о таких подходах можно почитать в статье Саши Инкина «Компоненты-агностики в Angular».
Тем не менее мы контролируем базовый UX, чтобы вам не приходилось о нем думать: например, при фокусировке инпута с клавиатуры тултип покажет подсказку через секунду автоматически, чтобы screen reader прочитал ее:
Технологичный
Мы очень чтим девелоперские практики и стараемся придерживаться близкого к идеям самого фреймворка Angular-подхода.
Мы не боимся работать с DI, все наши компоненты в OnPush, а на всем проекте включен strict-режим TypeScript’а — к типизации мы тоже относимся трепетно. Одним днем вы решите перейти на SSR, и наши компоненты в нем не сломаются.
Вы можете не беспокоиться о неожиданном значении, выходящем за рамки возвращаемого типа, а наши компоненты сами выведут ассерт в дев моде, если вы передадите в них что-то не то :)
Многообразный
Наш кит очень большой, в нем больше 130 UI-компонентов, десятки директив, токенов и различных инструментов.
Уже сейчас он позволяет быстро реализовать почти любую идею интерфейса. Но список будет постепенно расширяться: у нас есть идеи ближайших компонентов, а еще мы открыты к запросам и предложениям.
Как начать использовать
Заходите на официальный сайт и в документацию библиотеки. Смотрите, изучайте и следуйте инструкциям:
taiga-ui.dev
Если вам хочется поддержать нас или было бы интересно понаблюдать за развитием библиотеки — ставьте звездочку и подписывайтесь на Taiga UI в Github. Там можно задать любые вопросы, предложить идею или даже контрибьютить в код.
Еще с нами можно связаться в нашем канале в дискорде Angular. Общение там идет на английском языке, но при необходимости мы будем рады сделать отдельное коммьюнити и на русском.
Хотите узнать больше?
В ближайший четверг, 14 января, мы проведем стрим на нашем новом Twich канале. Начнем в 19-00 по МСК.
Расскажем больше про проект, презентуем его структуру, основные части и особенности. Постараемся ответить на любые ваши вопросы про Taiga UI, Angular или разработку библиотек компонентов.
Не прощаемся
Мы планируем писать более подробные статьи о том, как мы организуем и разрабатываем наши библиотеки. Такие статьи помогут вам лучше понимать работу нашего кита, а также объяснят разные приемы и практики разработки легко переиспользуемых компонентов на Angular, которые могут сильно выручить и в проектной разработке.
Поделитесь мнением о Taiga UI и расскажите, о каких компонентах, инструментах или процессах вам хотелось бы почитать в первую очередь?