Привет, Хабр! Сегодня мы хотим поделиться нашим опытом создания собственной платформы микрофронтендов и постепенной миграции веб-сайта компании на микросервисы. В этом посте вы узнаете, как мы пришли к этому решению, каким образом организовано тестирование фрагментов сайта, а также немного о повседневных задачах разработчиков, которые создают компоненты для такого модульного сайта. Если вы тоже занимаетесь микрофронтами или планируете это делать, обязательно делитесь опытом и присоединяйтесь к нашей дискуссии.
Микрофронтенды — очень перспективное направление, однако теории по этой теме намного больше чем практики. Леруа Мерлен уже прошла часть этого пути, и мы хотим поделиться с вами нашим опытом.
Вообще работа с микрофронтами — в любом случае новаторский проект. Мы хотели создать новый, более гибкий сайт, обеспечив server side rendering (генерация статической html-разметки) с соответствующей оптимизацией для пользователей, так и для SEO. Кстати, оптимизация под поисковики была важной задачей, потому что именно она помогла “продать” проект бизнесу, показав реальный результат в виде уменьшения TTM (Time To Market).
Создание платформы микрофронтендов Okapi
Начнем с того, как мы пришли к этому решению. Некоторое время наш сайт работал на базе Bitrix. Функционировал он нормально, но мы были сильно ограничены в масштабировании и по мере появления новых идей развития e-com, возникали различные технические ограничения. А поскольку мы хотим быть более гибкими, стильными и молодежными увеличить долю оборота e-com, нужно было что-то менять.
К идее микросервисов на фронтенде мы пришли не сразу. Еще до этого, в 2016 году стартовал проект Elbrus по переходу на новую платформу AEM (Adobe experience manager). Это, конечно, не самое популярное в России решение, но оно явно было функциональнее Bitrix. И Леруа Мерлен окончательно переехал на AEM в апреле 2019 года, когда мы перевели на новую платформу регион с самым большим трафиком — то есть Москву.
Спустя некоторое время мы заметили, что имеем длинный релизный цикл, большой срок регрессивного тестирования. Все это формировалось как снежный ком, из-за влияния команд друг на друга. Фактически мы получили монолит, которым сложно управлять, и который сложно развивать. Командам разработки приходилось достаточно долго выносить новый функционал в продуктив. Ведь если мы готовим релиз, и в каком-то компоненте обнаруживается критичный баг, приходится ждать его исправления, даже если сама задача не такая уж важная. К тому же на рынке наблюдался (да и сейчас наблюдается) дефицит компетентных разработчиков под AEM. Мы сотрудничали с подрядчиками, а найти свободных людей просто на рынке было невозможно. Именно тогда было принято решение переходить на микрофронтовую архитектуру, чтобы предоставить различным продуктовым командам свой микрофронт, который они создают, развивают и запускают независимо от коллег.
Создание платформы микрофронтендов Okapi
Посовещавшись, в середине 2019 года мы начали создавать собственную платформу для работы с микрофронтами на базе React.
Okapi — это одновременно набор библиотек и небольшой сервер приложений с использованием библиотеки react, которые используют команды Леруа Мерлен для создания микрофронтендов. Сейчас мы имеем платформу, которая обеспечивает работу и связки между микрофронтендами. Первая версия библиотеки была готова примерно через год. Конечно, реализация подобной инициативы потребовала найма новых разработчиков, и ребята продолжают присоединяться к командам микрофронтендов, потому что нам нужны дополнительные руки и опыт, а для разработчиков подобный проект — возможность поработать с чем-то интересным.
Как именно все это работает
Для начала немного терминологии и уточнений из схемы архитектуры:
Микрофронтенд - самостоятельное приложение, имеющее собственный адрес и публичный API
Виджет/ремоут - компонент, предоставляемый микрофронтендом, который пере используется другими микрофронтендами (кнопка, форма, шапка приложения и т.д.).
BFF - Backend for frontend - сервер, выполняющий запросы к внешним сервисам и подготавливающий полученные данные в удобной для микро фронта форме.
Service Discovery - сервис передачи данных между приложениями.
AEM Dispatcher - Adobe Experience Manager Dispatcher. В этом контексте он управляет информацией о страницах и данными.
Каждый микрофронтенд - это приложение (App1 , App2), которое использует библиотеку Okapi. При запуске приложение сообщает в Service Discovery своё имя и адрес сервера, на котором находится. Service Discovery рассылает всем зарегистрированным приложениям обновленные данные. В итоге, у каждого приложения всегда есть актуальная схема других приложений.
Клиент делает запрос к App1. Запрос приходит на AEM Dispatcher, который редиректит его на нужный микрофронтенд. App1 через BFF1 запрашивает у AEM Dispatcher информацию о запрашиваемой странице, а у внешних сервисов необходимые данные. App1 формирует html страницу (SSR), куда добавляет ссылки на статические ресурсы на CDN и скрипты аналитики. Клиент получает страницу, скачиваются клиентские бандлы приложения и библиотека React и происходит гидрация - построение SPA на основе html с микрофронтенда. При переходах внутри микрофронтенда - SPA делает запросы в BFF для получения данных о странице, не задействуя SSR. Если клиент переходит на другой микрофронтенд (App2), то App1 проверяет есть ли у него информация об этом микрофронтенде, если нет - она запрашивается у Service Discovery. App 1 делает запрос к App 2 за его расширенной конфигурацией со списком опубликованных ремоут компонентов, ссылками на клиентские бандлы и стили. App 1 добавляет в свой роутер роуты из App 2 и подключает его клиентские бандлы к себе. Происходит переход на другой роут без перерисовки страницы.
Чтобы продуктовые команды могли работать максимально эффективно, за год мы подготовили не только библиотеки Okapi, но также связанные сервисы — репозиторий с шаблоном для создания базового приложений/микрофронтенда с уже настроенными инструментами, настроенный CI/CD, дизайн систему и прочее.
Обновление версий нашей библиотеки okapi происходит через NPM Registry, который установлен на серверах компании. Чтобы выкатить новую версию, мы создаем changelog через Change Set с описанием внесенных изменений, которые мы внесли. Если предложенные изменения были проверены и одобрены, формируется итоговый Change Set из всех текущих коммитов, а обновленный код переезжает в продуктив, а номер версии библиотеки увеличивается на 1 с помощью инструмента "Lerna".
Решаем проблему переиспользования
Сейчас мы работаем над расширением возможностей микрофронтендов — над Remote-компонентами. Это виджеты, которые можно переиспользовать на разных микрофронтендах.
Для решения переиспользования кода/компонентов мы построили схему взаимодействия.
Микрофронтенд A имеет компонент для переиспользования. Микрофронтенд Z запрашивает по сети компонент от микрофронтенд A и использует у себя в приложение. При этом все контракты и логика сохраняются, а также все работает с поддержкой SSR. Такими компонентами являются шапка, подвал карусели товаров и тд. Так мы решаем основной вопрос потребления и распространения кодовой базы.
Сложности на пути
Конечно, не все складывалось гладко. Вообще сложностей было много, они встречались из-за того, что мы создавали на тот момент принципиально новый инструмент. Систему, которая может обеспечивать работу микрофронтендов с поддержкой SSR. При разработке самого решения мы пытались опробовать много гипотез, при реализации конечных микрофронтендов с использованием нашего инструмента - мы делали дополнительное обучение/мастер классы по принципам работы с изоморфными приложениями, а также по правилам поддержания высокого качества кода, что закладывалось с учетом quality first подхода. Что выражается в автоматизации всего и вся - исключая человеческий фактор, в высоком проценте покрытия unit-тестами (минимум 80%), однако мы понимаем что это false positive значение, которые мы стараемся балансировать с помощью интеграционных и e2e тестов. Вследствие нам пришлось ставить рамки для разработчиков, чтобы они писали тесты на все свои кейсы
Можно выделить основные моменты, которые точно будут актуальны для всех, кто захочет строить подобную архитектуру у себя.
Когда люди начинают работать в новой системе, очень сложно бывает понять, как “играть по новым правилам”. Сразу создать команду для разработки и поддержки микрофронтенда, которая понимает, что она делает — нереально. Для помощи и быстрого старта мы обеспечили команды большим количеством структурированной документации на любой вопрос. Если вдруг возникла форс-мажорная ситуация при которой ответа в документации вдруг не нашлось - команда платформы okapi может проконсультировать другие команды микрофронтендов в соответствующих публичных чатах, с их помощью мы и вносим недостающие части в документацию и актуализируем знания.
Было сформулировано правило: если возникает проблема, мы ее решаем и добавляем раздел в руководство. В результате за год появилась база знаний, которая на 95% покрывает развертывание, CI/CD, ревью кода и так далее. Но здесь очень важно соблюдать баланс между количеством документации и ее полнотой. Если руководств слишком много — никто не будет их читать, а если мало — они не помогут решить проблемы.
Чтобы упростить адаптацию, мы создали систему светофора. Продуктовые разработчики прогоняют его через инструменты анализа в каждом коммите, который принадлежит pull request’у. Такими инструментами является “Sonar qube”, typecheck от typescript, все возможные линтеры “eslint”, “stylelint” проверка каммитов на правильное название соответствующее шаблону номеров задач в таск менеджере и тд. В процессе работы над первыми микрофронтендом мы определили три категории оценок - светофор.
Красный - Запрещенные действия. К примеру: отсутствие изоляции стилей между микрофронтенда
Желтый - не рекомендуются. К примеру: некоторые решения или библиотеки много весят в сборке и аффектов на bundle size
Зеленый - Рекомендации для команд работающих с микрофронтенда. К примеру: Использовать инструменты и настройки, что уже заложены в микрофронтенде и не редактировать без особой нужды правила/конфигурации инструментов проверки кода.
Планы развития
Существует проблема - сейчас создание новых микрофронтендов и их присоединение, а также настройка pipeline и тд - происходит вручную силами нескольких человек и некого количества времени. Разумеется это дорогая операции и мы решили инвестировать наше время в создание полностью автоматизированной системы. Мы хотим сделать так, чтобы пользователи заходили на какой-то дашборд и могли буквально “накликать” себе микрофронтенды без нашего участия. Это большие планы на ближайшие годы, и поэтому наш бэклог на сегодняшний день полон интересных и перспективных задач.
Результаты
Подведем небольшие итоги. Создав для себя Okapi, мы добились полной автономности продуктовых команд, которые получили независимые релизные циклы, без какого-либо влияния на другие приложения. Кроме этого сокращение TTM (time to market) в некоторых случаях достигало нескольких раз. Так, как ранее мы могли ждать релиз фичи несколько недель и даже месяцев, то сейчас это сократилось до одного спринта, а если задача срочная - то нескольких дней.
На этом долгом пути в несколько лет и кучи итераций мы готовы рекомендовать подход микрофронтенды, если вы уже крупная компания, которая очевидно страдает от долгих или конфликтных релизов. Если вы готовы инвестировать время и деньги в реализацию такого подхода с технической стороны, обучение сотрудников и налаживание инфраструктуры и процессов вокруг. Вам нужно будет написать очень много внутренней документации на каждый чих. Иначе этот большой титан может рухнуть и покажет себя еще хуже чем проверенный временем монолит. Микрофронтенды - это не панацея, это один из способов решить боль или усилить ее.
В настоящий момент на сайте запущено уже 7 микрофронтовых приложений, через которые проходит большая часть пользовательского трафика, а еще 9 приложений готовится к релизу. В их числе главная страница, карточка товара, личный кабинет пользователей В2С и В2В и прочие разделы с менее интенсивным трафиком.
Комментарии (10)
nin-jin
07.10.2021 07:42Насколько я понял, у вас получилось динамическое связывание сторонних компонент. Что будет, когда вам на одной странице надо будет отобразить по 1 компоненту от разных продуктовых команд? 10+запросов? А если один из них не догрузится, что увидит пользователь?
cloudofgeorge Автор
07.10.2021 13:50Сейчас мы прорабатываем объединение схожих запросов, однако если запросы с разных источников (разные микрофронтенды, условно 10+), то столько же их и будет по факту. Для компонентов предусмотрены fallback, специфический для каждого компонента
nin-jin
07.10.2021 14:44А ведь можно сделать бандл куда включить все необходимые компоненты. Тогда будет ровно 1 точка отказа. А не 10.
Peregrinus
А почему выбрали React, а не что-то более эффективное, типа $mol?
cloudofgeorge Автор
Нас подкупили моменты гибкости и поиск разработчиков в разы проще специфических решений/фреймворков. А также мы делали ставку на SSR, который вполне реализовывается с react
jMas
Расскажите, все таки АЕМ вам помог или это все таки попытка сбежать от этого продукта? На сколько я понимаю, почти у всех есть дефицит с кадрами, владеющими АЕМ. Плюс, вы используете их SPA?
dagot32167
имхо, он помог понять, что мы хотим и куда следует развивать продукт. какие ограничения для нас представляет монолит, готовы ли мы с ним мириться и соответствует ли он планам нашей трансформации из функциональных в продуктовые команды.
У АЕМ есть свои плюсы и минусы, а так же огромный функционал, который он предоставляет, но он не будет использован по тем или иным причинам.
SPA подход в АЕМ, стабилизировался намного позже начала реализации платформы микрофронтов. Да, в рамках эксперимента мы попробовали реализовать часть функционала на aem spa react. Но это не решение проблем. Просто перенос рендера со стороны htl на react и клиентский роутинг с обменом портянками json. Ведь билд и поставка так и оставались в зоне ответственности АЕМ (по крайней мере по тем рекомендациям со стороны adobe, которые существовали на тот момент). А это опять возвращает нас к длинным релизам и конфликту фич разных команд.
На сколько знаю, некоторое время назад, АЕМ таки смог реализовать Headless режим адекватный, но еще раз повторюсь, когда начинали разработку платформы микрофронтов, у АЕМ это было в зачаточном состоянии с весьма скудной документацией и необходимостью обновить версию АЕМ (что так же весьма не приятный процесс)
nin-jin
А много на рынке разработчиков под Okapi?
Ну, на $mol SSR ещё проще реализуется благодаря контекстам окружения и изоморфности. И для этого не надо целый фреймворк над фреймворком пилить.
cloudofgeorge Автор
Саму окапи разрабатывает и поддерживает сформированная команда. Но для использования микрофронтендов в других командах минимально достаточно знать библиотеку react и нюансы SSR, остальное опционально относительно нужд самой команды микрофронтенда
nin-jin
А, ну так и я могу сказать, что для использования $mol достаточно лишь знать TS и основы реактивного программирования. Остальное - опционально, включая сам $mol.)