Привет, Хабр. Меня зовут Артем Арефьев, я руковожу Frontend-разработкой в направлении продукта для учеников в Учи.ру. Фронтендом занимаюсь уже 11 лет, шесть из которых работаю у нынешнего работодателя. Еще принимаю участие в проектах Open Source (например, внес вклад в проект Lerna), несколько лет был наставником в «Хекслет». Хочу рассказать о том, как у нас в Учи.ру возникла необходимость в создании библиотеки компонентов, почему первое решение не сработало, какие выводы мы сделали и чем закончился наш проект библиотеки. Начать стоит с того, что компания Учи.ру, как и любой продукт, развивалась постепенно. В самом начале это было монолитное приложение, над которым работала одна команда. Но проект разрастался, и появилось несколько команд, каждая из которых сфокусировалась на своей предметной области. Постепенно количество фичей у команд выросло до такого объема, когда зависимости начинают влиять на сроки реализации. Поэтому монолит начали делить на независимые приложения. Командам стало проще делать фичи и, соответственно, быстрее катить их на прод. Но возникли две проблемы. Различия в дизайне: разные цвета и размеры элементов, шрифты, UX. Наши основные пользователи — школьники, которые в этом разнообразии путались. Одинаковые по сути, но отличные по дизайну элементы дети воспринимали как разные, что осложняло пользовательский опыт. Из-за разделения фронтенда каждый дубль элемента — модальное окно, кнопку, инпут — приходилось поддерживать отдельно, на это тратились ресурсы. Чтобы не путать пользователей и экономить время, мы решили внедрить общую библиотеку компонентов. Работа предстояла большая ввиду нескольких факторов: Компоненты должны были работать с разными инструментами, поскольку в компании есть проекты на TypeScript, на React в связке с Redux или MobX, на Vue, несколько приложений на Next.js, лендинги в Tilda. Ученики занимаются на платформе как дома, с ноутбуков и смартфонов, так и в школе, на компьютерах со старыми версиями браузеров. Компоненты должны работать у большинства наших пользователей и не сильно нагружать страницу. Нам подходили веб-компоненты, но они работали только в современных браузерах. Поэтому мы искали свое решение на основе этой технологии. Вариантов было много, но мы остановились на Stencil.js, поскольку у него уже была реализована поддержка с React и Vue.  Необходимо было определиться, кто будет заниматься разработкой библиотеки. Сервисных команд у нас не было, создать специальную команду мы не могли. Было несколько проектных команд, которые помогали отделам без разработчиков, и продуктовые команды, которые непосредственно занимались продуктом. Мы решили, что лучше всего поручить создание библиотеки самой опытной проектной команде, а продуктовые команды смогут сами вносить изменения в компоненты при внедрении. Дизайнера взяли в одной из продуктовых команд. В первую очередь было решено сделать те элементы, которые, как нам казалось, везде пригодятся: компоненты для работы с текстом, интерактивные компоненты и сетку. Мы запустили всю эту историю 13 июля 2020 года. Через месяц у нас появилась самая первая версия библиотеки, но в ней еще не было компонентов. Сами компоненты делались в течение следующих пяти месяцев, мы их тестировали, правили баги. Процесс создания компонентов для библиотеки представлен на рисунке ниже.  Такой долгий срок для нас стал сюрпризом, но тут роль сыграли: Высокая сложность разработки. Чтобы создать компонент, недостаточно было реализовать логику и написать стили. Для обеспечения полноценной поддержки в проектах на React и Vue мы разрабатывали для каждого разные обертки (причем из-за изменений в Vue3 сделали еще одну обертку). В некоторых компонентах двустороннее связывание в Vue работало только в тестах, а при внедрении в проект — нет. И узнавали это мы, соответственно, только когда внедряли. Расположение нескольких версий одного компонента на странице. Эту проблему мы пытались решить, добавив префикс. При маунте компонента префикс должен был заменяться на версию. Это решало проблему коллизий, но, к сожалению, не решало проблему со скоростью загрузки страниц. Все потому, что для каждой патч-версии получался отдельный файл. Трудности при создании компонентов. Чтобы их сделать, недостаточно было знать Stencil.js. Была куча внутренних особенностей, которые хотя и были задокументированы, но все же вызывали вопросы. В итоге продуктовым командам трудно было работать с компонентами, и они постоянно «дергали» проектную команду, которая занималась библиотекой. А ведь библиотека не была основным проектом разработчиков, времени на нее было не так много. Отсутствие согласованности по дизайну. Вместо того, чтобы использовать компоненты как есть, дизайнеры продуктовых команд экспериментировали. В итоге путаница в стилях сохранилась: элементы отличались отступами, скруглением, размерами. Мы не договорились, что на изменение дизайна нужно серьезное обоснование. Первой версией библиотеки начинали пользоваться четыре продуктовых команды, три из которых от нее отказались, потому что инструмент получился неудобным. Летом 2021 года проект заморозили. И, по сути, это был провал. Летом 2022 года мы сформулировали новую цель направления по работе с учениками — улучшение взаимодействия пользователей с продуктом. В рамках этой цели решили создать единый стиль всех проектов, а для этого — возродить библиотеку компонентов, исправив недочеты прошлой версии. Мы решили не восстанавливать прошлую версию (в ней было очень много багов, и мы опасались потратить все время только на их исправление), а создать новую, основанную на имеющейся. В этот раз у нас были более жесткие сроки, предусмотренные OKR, а участвовать в разработке могли только продуктовые команды, поскольку в направлении работы с учениками сейчас только такие и есть. Мы решили, что в этот раз не будем отдавать создание библиотеки «на откуп» лишь одной команде, а станем работать над ней все вместе. Обсудили с коллегами пользу, которую потенциально библиотека может принести: например, когда она появится, всем будет удобнее делать фичи. И договорились использовать стратегию InnerSource — это когда подать идею и внести свой вклад в проект может каждый из коллег.  В создании библиотеки участвовали дизайнеры всех продуктовых команд (под руководством лида дизайна в направлении) и фронтенд-разработчики, которых курировал я.  Также, наученные предыдущим опытом, мы приняли важные правила: В библиотеку попадают компоненты, которые точно нужны в данный момент и будут использоваться в разных местах, а не те, которые «возможно, пригодятся». При разработке фичи рассматриваем ее компоненты: если они могут впоследствии понадобиться для других фичей, создаем их через библиотеку.  Компоненты используются без изменений. Если очень нужно, то вопрос обсуждается. Если договориться не удается, у команд всегда есть возможность сделать свою библиотеку, основанную на текущей. Все вопросы мы стараемся решать через канал оперативной коммуникации. В целом, вторая версия библиотеки оказалась удачной и успешно используется в работе. Уже в течение месяца мы смогли довести ее до состояния, когда компоненты решают задачи на проде. Мы в целом сделали больше компонентов, потому что в проекте принимало участие больше людей.  Конечно, остались и определенные вызовы. Например, из-за того, что за библиотеку отвечают все и сразу, сложно понять, кому браться за доработку компонентов. Поскольку библиотека — не основная задача, то времени обычно нет ни у кого. В нашем направлении нехватка времени особенно сильна, потому что, повторюсь, в него входят только продуктовые команды. У некоторых нагрузка может быть так высока, что не всегда получается поработать даже с техдолгом. Как правило, наши разработчики считают, что дорабатывать должен тот, кто изначально делал компонент. Но я ратую за коллективную ответственность и обращаю внимание: если у кого-то появилась инициатива, он может сам внести изменения. Или отправить на review — все инициативы мы собираем, обсуждаем, отправляем в бэклог, приоритезируем. И в дальнейшем ими занимается тот, у кого появилось время. Теперь ни одна команда не игнорирует библиотеку: ведь мы работаем с обратной связью достаточно быстро, и есть реальная возможность самому внести изменения. Наоборот, присоединиться к библиотеке хотят команды из других направлений. Кажется, что есть запрос на расширение инструмента на всю компанию. Из этой истории можно сделать важный вывод — разработкой общих проектов, которые несут пользу всему направлению или компании, нужно заниматься сообща. Используйте стратегии InnerSource: формируйте сообщество вокруг инструмента; создавайте культуру сотрудничества; мотивируйте и поощряйте людей, которые вносят вклад в развитие инструмента.  Чем быстрее инструментом начнут пользоваться, тем быстрее вы получите фидбэк, по результатам которого уже примете решение, стоит ли продолжать.  Frontend разработчик