Библиотека как продукт: от папки в проекте до международного опенсорса

Kate

Administrator
Команда форума
Работа над общей библиотекой сильно отличается от работы в продуктовой команде. Но разработчики библиотек тоже проходят длинный путь становления своего продукта, причем, в отличие от приложений, часто без помощи менеджеров или бизнес-аналитиков.

Давайте посмотрим, из чего может состоять путь крупной библиотеки, как планировать действия команде разработки и какие челленджи могут встретиться на нем.

Статья написана по опыту разработки фронтовых библиотек и с советами вокруг JS-экосистемы, но часть идей будет полезна и для других направлений.

14b000646b3284e2f540944975ed8d01.png

Посмотреть в формате видео​

11 сентября прошел юбилейный MoscowJS 50, где я выступал с одноименным докладом. Запись выступления можно посмотреть на Ютубе. В этой статье я хочу донести те же идеи, но в текстовом формате: выбирайте, что вам ближе!

О чем статья​

За последние три года я разработал и выпустил много библиотек: маленькие модули для пары команд, библиотеки для крупного отдела фронтенда, нишевые опенсорсы для решения конкретной проблемы и огромную библиотеку компонентов Taiga UI.

Taiga UI сейчас содержит больше 130 компонентов и еще несколько сотен разных Angular-сущностей. Но выросла она из маленького пакета внутри отдела, плавно развиваясь сначала в нем, а после и во всей компании.

Этот опыт натолкнул меня на мысль, что разработка библиотеки — совсем не однотипный процесс. Пока растет библиотека, у команды может сильно поменяться деятельность, могут появиться нетипичные обязанности, а разработчикам важно продумать и проработать, как перестраиваться под новые условия.

Я разбил путь развития библиотеки на пять этапов. Но для любой конкретной библиотеки их количество может меняться.

Для каждого этапа опишу свое видение, что должна делать команда разработчиков и как планировать движение дальше. Покажу и все потенциальные ошибки и проблемы, которые могут замедлить или вовсе остановить развитие.

Замечу, что описанные в статье наблюдения и советы так или иначе применимы к любому модулю, пакету или библиотеке в компании.

Этап 1. Папка в проекте​

Этап отчасти шуточный, но все же существует. Это ситуация, когда вы работаете над проектом и хотите вынести общую логику в какую-нибудь папку с тулингом.

Работа над этой папкой не отличается от работы над самим проектом. Но однажды к вам может прийти другая команда и сказать, что тоже хочет пользоваться вашими инструментами. Тогда эту папку можно превратить в отдельный пакет.

Этап 2. Отдельный пакет​

Совет: если вы используете решение для монорепозиториев, то часто с ним идет CLI, позволяющая генерить библиотеки одной командой. Генерация полноценного пакета будет занимать столько же времени, сколько и создание папки. Но так вы будете делать более общее решение, а при необходимости сможете вынести пакет в отдельный репозиторий и потратите не больше пары минут.

На этом этапе у вас есть пакет, который уже используют в соседних проектах. Тут важно грамотно подойти к организации работы с библиотекой. Возможны несколько сценариев.

Плохо: случайные люди контрибьютят, случайные люди ревьюят или никто не смотрит. Это путь в никуда, через некоторое время библиотеку в библиотеку станет невозможно контрибьютить, а после и использовать. Избегайте таких ситуаций.

Нормально: контрибьютят все еще случайные люди по необходимости, но есть заинтересованные ревьюеры. Каждый Pull Request рассматривают люди, которые примерно осознают общую архитектуру библиотеки и заинтересованы в ее развитии.

Хорошо: есть выделенная команда мейнтейнеров библиотеки. Они организуют контрибьютинг, поддерживают библиотеку в едином стиле, смотрят PRы, иногда могут ответить на вопросы или закодить нужную фичу для проектов.

На этом этапе появляется собственный релизный цикл, документация, которая позволяет не отвечать на одни и те же вопросы изо дня в день, а также минимальная поддержка — пока все и так примерно знают, к кому обратиться за помощью.

Еще вы можете спокойно делать ломающие изменения: сильно менять API или заменять одни сущности другими. Надо будет лишь обойти пару команд, может быть, где-то помочь с переездом.

Если же ваша библиотека развивается гармонично и приносит пользу, то ей захочет пользоваться все больше команд. Так она перерастет в решение на отдел.

Этап 3. Решение на отдел​

Где-то это может быть этап не отдела, а всей компании, а где-то — одной группы разработки. Для меня ситуация примерно такая:

  • библиотеку используют 10+ проектов из одной предметной области;
  • разработчики библиотеки и ее потребители незнакомы;
  • у библиотеки есть выделенная команда разработки. Не обязательно на фултайм, но важно, чтобы развитие библиотеки было частью их регулярной рабочей деятельности.
Тут разработчики библиотеки должны начать задумываться о кастомизируемости сущностей — делать более общие решения, которые команды смогут гибко подстраивать под свой конкретный кейс. Если не думать об этом, то разработчики проектов будут регулярно приходить и просить докрутить общий инструмент под их конкретный кейс, что отнимает много времени и засоряет кодовую базу.

На этом этапе уже должна быть неплохая документация, чтобы предотвратить рутину с повторяющимися вопросами и организованная поддержка пользователей.

Как организовать поддержку внутри отдела.

Создайте чат в мессенджере, куда сможете постить новости и обновления библиотеки, а пользователи — приходить с вопросами и проблемами. Тут же можно вспомнить практику дежурств: ставить одного члена команды в течение недели разгребать все входящие обращения в чат. На следующей неделе дежурный может меняться.

Проводите демо и показывайте разработчикам проектов, как правильно работать с вашей библиотекой, новые полезные фичи и мастер-классы. Командам будет проще понимать библиотеку, а вы на таких встречах сможете получать обратную связь.

Используйте контрольные опросы. Они показывают, все ли идет в порядке: решает ли библиотека нужные проблемы, удобно ли ей пользоваться, в нужном ли направлении она двигается.

Работа с ломающими изменениями.

На этом этапе ломающие изменения все еще возможны, но должны быть редкими. Командам надо помогать с переездом на новую версию, а может быть, даже начинать автоматизировать этот процесс.

Тут может помочь практика deprecated — когда вы хотите кардинально изменить API-сущность, но вместо изменения маркируете ее как deprecated и добавляете новую сущность с измененным API, которую будете дальше поддерживать.

Такой подход позволяет командам обновлять библиотеку, даже если они пока не готовы к переезду на новые сущности. Когда у них появится время на разбор технического долга — обновятся.

Пример лейбла deprecated с витрины библиотеки Taiga UI
Пример лейбла deprecated с витрины библиотеки Taiga UI

Этап 4. Решение на компанию​

На этом этапе библиотека распространилась на всю компанию: ее используют десятки, а может, сотни проектов разной направленности. Библиотеку не нужно пиарить, она стала стандартом: новые люди приходят в компанию и им сразу ее выдают.

Тут разработчики библиотеки уже серьезно думают наперед и делают переиспользуемые решения. И у них появляется деятельность Developer Advocate.

Developer Advocate — целая профессия. Она распространена на западе, но у нас встречается редко. Подробнее о ней можно почитать в статье такого адвоката из Microsoft — Уэссима Чехэма.

Мейнтейнерам пора заботиться о том, удобно ли другим разработчикам использовать их библиотеку. Смотреть взглядом пользователя, искать проблемы, узнавать про сложности и постоянно улучшаться.

К этому моменту и поддержка, и документация должны быть отлично организованы, иначе команда погрязнет в ответах и консультациях. Работа становится более публичной — можно начать вести роадмап, чтобы все понимали, когда ждать крупные фичи.

Здесь же может появиться проблема ранжирования задач по приоритетам: будут приходить люди из разных отделов и объяснять, почему именно их задачу надо сделать быстрее всего. Вам же надо будет как-то организовать этот процесс или просто регулярно выбирать, что приоритетнее.

Для этого этапа я собрал несколько полезных практик.

InnerSource. Часть несложных, но интересных задач можно качественно заспекать и предложить коллегам на InnerSource. Как правило, разработка общей библиотеки сильно отличается от обычной проектной, поэтому разработчикам такое может быть интересно. Польза для библиотеки — люди приходят и делают часть работы. Мотивация контрибьюторов — разнообразить свои рабочие будни и получить новый опыт.

664c7b6c2851881b04716d9917293161.png

Пример, как было организовано в Taiga UI до опенсорса: краткое описание мотивации для разработчиков и автоматический сбор задач из Jira с лейблом

Автоматизация миграций. Если ломающие изменения на этом этапе и бывают, то мажорные версии готовятся долго и максимально автоматизируются. Без автомиграций даже небольшие изменения в публичном API могут стоить десятки или сотни человеко-часов.

Автоматизировать обновления тоже можно по-разному: мы начинали с простых js-скриптов, которые запускали в проекте через npx, — и они правили файлы силами Node JS и регулярных выражений. Такой же скрипт можно запускать на postinstall новой версии вашего пакета.

Более продвинутый вариант — использовать специализированный тулинг, который позволяет работать с абстракцией над файловой структурой. Например, в Angular-мире существуют Angular Schematics, а если ваши проекты построены как NX-монорепозитории, то можно использовать NX Generators.

Общие рекомендации, как пройти этот этап.

Не пытайтесь угодить каждому. Делайте максимально общие решения и не поддавайтесь на просьбы подкрутить их под потребности одного конкретного проекта.

Не делайте ломающие изменения. А если делаете, то не забывайте сопроводить их автомиграциями.

Будьте готовы к новым обязанностям. Появляется много новых дел, и может показаться, что команде становится тяжелее. Я считаю, что закрывать эти потребности новыми людьми — неправильная тактика. Как правило, работы больше не становится, она лишь становится другой, поэтому если команда открыта новому, то сможет быстро привыкнуть к измененному укладу.

Этап 5. Внешний продукт​

Если вашим решением пользуются десятки разработчиков продуктов для разных предметных областей, с большой вероятностью оно будет полезно и людям вне компании.

Потенциал на этом этапе безграничный, количество пользователей может расти кратно и за короткие сроки. Кроме того, внешний продукт может даже стать отдельным бизнесом для вашей компании или просто давать ряд косвенных бенефитов.

На этом этапе сначала нужно задаться вопросом: чего мы хотим от внешнего продукта? С одной стороны, можно сделать платное решение, которое другие компании будут покупать, чтобы справиться с проблемой быстро и дешево. С другой — можно выложить все в опенсорс и развивать публично.

Давайте рассмотрим эти крайности подробнее.

e9123e638a5ac0ee81e0a5e3f81d63df.png

Все продавать. Ситуация, когда мы превращаем наш инструмент в небольшой отдельный бизнес компании. Командой разработки на этом этапе уже точно не обойтись, нужны будут специалисты для b2b-маркетинга и процессы с учетом новых пользователей.

Саму команду разработки тоже придется расширять. Когда компании платят вам деньги, то ожидают собственную линию поддержки, возможность запрашивать новые фичи и так далее. У команды появляется значительно больше работы.

Все опенсорсить. Ситуация, когда мы просто берем и выкладываем наше решение в публичный доступ. Опенсорс дает целый ряд прямых и косвенных бенефитов вашей компании, а работа над ним не будет занимать у команды больше времени, чем занимала прежде. Обо всем этом я подробно написал в своей недавней статье «Пять причин для ИТ-компании полюбить опенсорс».

Пожалуй, единственный момент, который отличает команду разработки крупной внутренней библиотеки от опенсорсной, — все разработчики или большая их часть должны уметь общаться, ревьюить код, отвечать на вопросы и писать документацию на английском. Иначе будет тяжело найти и сохранить пользователей. В остальном все так же: крепкие разработчики и хорошие адвокаты, умеющие объяснить, чем технология полезна, ответить на вопросы и показать примеры.

Рабочий день команды меняется, потому что теперь нужно развивать не только саму библиотеку, но и комьюнити вокруг нее.

Еще возникают дополнительные вопросы приоритизации, потому что на этот раз придется выбирать между запросами из компании и хотелками внешних пользователей. Этот баланс нужно научиться держать и перестраивать по необходимости.

Работа в опенсорсе — это полная публичность вашей деятельности. Тут не получится занести в библиотеку временный «костыль» или сделать минорную фичу не самым красивым образом. Комьюнити плохо воспринимает такие решения.

Все ломающие изменения точно пора автоматизировать. Оно и логично, ведь необходимость поправить буквально одну строчку руками приведет к немыслимому количеству затраченного времени по всему миру. Меня пугает такая мысль.

Среднее решение. Впрочем, необязательно впадать в крайности. Можно и прийти к чему-то среднему между платным решением и опенсорсом.

Например, вы можете иметь полностью бесплатный и открытый исходный код, но предлагать дополнительные платные опции:

  • консультации, помощь по внедрению, отдельную быструю линию поддержки;
  • дополняющие продукты. Например, для библиотеки компонентов таким продуктом может быть готовый стартер для админ-панели;
  • донаты и фича-ханты. На мой взгляд, это самый неудачный способ сколотить капитал, но несколько баксов на подписках получить можно.
А может, сразу в опенсорс?

Не обязательно долго развивать инструмент внутри компании, чтобы потом выкладывать в опенсорс. Это можно сделать в любой момент, если понимаете, что планируемое решение потенциально будет полезно не только в рамках вашей компании. Это рабочая модель, и я бы хотел подсветить пару плюсов и минусов такого подхода.

Минусы:

  • много работы на старте: вам нужно не только делать саму библиотеку, но и строить комьюнити вокруг нее;
  • может чуть сложнее развивать библиотеку, потому что при неудачном дизайне или необходимости сменить публичный API можно столкнуться с недовольством внешних пользователей подобными изменениями.
Плюсы:

  • вы делаете более общие и гибкие решения с расчетом на любой сценарий использования;
  • обратная связь и помощь от комьюнити помогут сделать библиотеку лучше.

Вместо заключения​

Моя идея в том, что нужно регулярно обдумывать, в правильном ли русле развивается ваша библиотека и какими делами заняты ее разработчики.

Совершенно нормально, если вы поняли, что ничего менять и не нужно: некоторым библиотекам лучше развиться до определенного этапа и из-за своей специфики остаться на нем навсегда.

Стоит рассмотреть и вариант опенсорса. Он приносит немного дополнительных хлопот, но дает большое количество преимуществ.

 
Сверху