13 июля 2023

🍇 Микрофронтенд: что это такое и зачем он нужен?

iOS-developer, ИТ-переводчица, пишу статьи и гайды.
В этой статье сравним разные способы организации микрофронтенда, изучим их преимущества и стратегии реализации.
🍇 Микрофронтенд: что это такое и зачем он нужен?
Данная статья является переводом. Автор: Aleksandr Guzenko. Ссылка на оригинал.

В течение последних нескольких лет фронтенд-сообщество активно обсуждает и использует термин «микрофронтенд» (далее МФ). Разные компании делятся своими подходами к организации такого архитектурного решения, но пока мало описания задач, которые МФ призваны решать в сети, критериев их применимости и ограничений в использовании.

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

Микрофронтенд: что это такое и зачем он нужен?

Прежде чем мы перейдем к определению МФ, давайте рассмотрим несколько проблем, с которыми можно столкнуться в проектах:

1. У вас большой проект

Размер проекта обычно субъективен и может быть определен эмпирически по объему функциональности и количеству разработчиков. Если у вас достаточно работы, чтобы озадачить 1-2 фронтендеров и при этом они не будут «толкать локти» – это маленький проект, 3-6 – средний, а больше 6-8 – уже большой.

2. У вас большая команда

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

Больше полезных материалов вы найдете на нашем телеграм-канале «Библиотека фронтендера»

3. У вас отличный функционал

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

Проблемы могут усугубляться при:

  • желании изменить стек;
  • наличии требования компании поддерживать семейство связанных проектов.

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

<i>Данное изображение и все последующие взяты <a href="https://hackernoon.com/breaking-the-monolith-a-comprehensive-guide-to-code-splitting-techniques" target="_blank" rel="noopener noreferrer nofollow">отсюда</a>.</i>
Данное изображение и все последующие взяты отсюда.

Таким образом, подход МФ — это разделение монолитного фронта на отдельные кодовые базы, хранящиеся в отдельных репозиториях, к которым имеют доступ отдельные подкоманды. При этом у них могут/должны быть свои демонстрационные стенды, тесты и циклы выпуска. Соответственно, микрофронт — это съемная часть интерфейса. Разделять по страницам не обязательно, функционал может быть сквозным (например, корпоративный ui-kit).

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

🍇 Микрофронтенд: что это такое и зачем он нужен?

Микрофронтенды vs Ленивая загрузка

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

Ленивая загрузка решает проблему производительности:

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

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

Время сборки vs время выполнения

Теперь поговорим о подходе объединения МФ в одно приложение. Что бы вы ни выбрали, для пользователя это должно выглядеть как единое приложение. Мерджить можно как на этапе сборки, так и динамически — во время выполнения кода на стороне пользователя.

Таким образом, все способы организации МФ можно отнести ко времени сборки или времени выполнения. У каждого есть свои плюсы и минусы.

Время сборки Время выполнения
Проверка типа + -
Версии + не имеет смысла
Независимое развертывание - +

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

Объединяя микрофронты во время сборки, вы не лишаетесь возможности проверять типы. В случае runtime union придется писать интеграционные тесты, чтобы фронт вдруг не «взорвался» на продакшене.

Управление версиями и независимое развертывание очень противоречивы:

  • Управление версиями означает, что вы можете взять любую версию МФ другой команды. Особенно это актуально, когда нужно провести дополнительную работу по обновлению зависимостей МФ от других. Каждая команда выбирает лучшее время для апгрейда.
  • Независимое развертывание дает больше автономии и независимости командам. Важно всегда использовать последние версии МФ. Это требует обратной совместимости.

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

Далее мы увидим примеры конкретных реализаций каждого подхода к объединению МФ.

Подходы к организации микрофронтендов

iframe

Самый старый способ организации МФ. iframe — это специальный тег для передачи адреса ресурса, который будет отображаться на основном сайте. В результате получается сайт на сайте.

🍇 Микрофронтенд: что это такое и зачем он нужен?

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

Эти преимущества достигаются за счет производительности, поскольку каждая вставка iframe приводит к нагрузке на ресурсы. Этого не избежать: попытки отладить и переподключить DOM-узел не сохранят ранее загруженные ресурсы, их придется скачивать заново. Вы можете свести к минимуму снижение производительности, настроив кэширование.

Для этого вам необходимо настроить инвалидацию кеша на основе времени для неизменяемых ресурсов. К счастью, все современные cli из коробки к собранным файлам js и css прикрепляют к названию небольшой хэш. К недостаткам этого метода относится неспособность поисковых роботов отрисовывать iframe для последующего индексирования.

Плюсы Минусы
Простота реализации Производительность
Логика и изоляция стилей SEO
Независимое развертывание
Фреймворк-агностик

Веб-компоненты

Фронтенд-сообщество давно ждало создания нативных компонентов, но в итоге они так и не обрели той массовой популярности, на которую многие рассчитывали. Три самых популярных фронтенд-фреймворка (React, Vue, Angular) по-прежнему создают компоненты по-своему.

Несмотря на возможность создавать МФ на веб-компонентах, на практике я такого не встречал. И это неспроста, существует ряд блокираторов:

  • Либо библиотеки Lit, либо Stencil недостаточно популярны и недостаточно распространены. Кроме того, на рынке не хватает специалистов, умеющих с ними работать или готовых учиться.
  • Экзотикой остаются угловые элементы или vue-custom-element. В нативной среде особого смысла их использовать нет. Если вы уже разбили приложение, то на обычные npm-пакеты, чтобы потом можно было подключать компоненты как угодно. Использование веб-компонентов с другими фреймворками неразумно, так как вместе с сгенерированными компонентами нужно подключить мини-версию фреймворка, на котором они были написаны.
  • Перенос сложных функциональных частей в веб-компоненты может быть дорогостоящим. Поскольку вам нужно будет настроить взаимодействие вашего компонента с остальной частью приложения, выделение целой страницы в отдельный пользовательский компонент может оказаться неоправданным.
  • Поисковые роботы не могут создать веб-компонент, и это повлияет на SEO-оптимизацию.
Плюсы Минусы
Подходит для сквозной функциональности Сложно реализовать
Совместимость с любым фреймворком SEO
Логика и изоляция стилей

NPM

Разработка с использованием пакетов npm имеет много преимуществ. Разработчики просто импортируют нужные им компоненты и файлы из библиотеки. При этом в проекте сохранена типизация, есть версионность. Сборка оптимальная: работает tree-shaking (удаление неиспользуемого кода во время сборки), и разработчики могут легко настроить ленивую загрузку.

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

Плюсы Минусы
Производительность Не имеет независимого развертывания
SEO Один стек
Проверка типа
Версии

Подмодули git (или другой способ создания монорепозиториев, таких как Lerna)

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

🍇 Микрофронтенд: что это такое и зачем он нужен?

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

Давайте посмотрим на различия между двумя методами:

  • Пакеты NPM, по сути, являются конечным, умеренно изолированным микропродуктом со своими собственными выпусками и версиями. Все сосредоточено на создании повторно используемого функционала. Но приложение может быть сложным/запутанным и отторгающим, поэтому упаковка большого монолита может быть довольно дорогостоящей. Вот здесь было бы разумно рассмотреть сабмодули, потому что они позволяют очень грубо резать репозиторий, когда мы перемещаем папку в отдельный репозиторий без какой-либо дополнительной подготовки.
  • Пакеты NPM могут быть вложены рекурсивно. Подмодули тоже, но на уровне сборки могут начать дублировать функционал, если один из подмодулей включить несколько раз в разные папки как отдельный подмодуль. В этом случае стоит использовать более плоскую модульную структуру.
  • Если вам нужно быстро выкатить фичу сразу во все пакеты, кросс-пакетная разработка может оказаться крайне неудобной. Хотя в подмодулях все остается по-прежнему, вы можете вносить изменения, затрагивающие другие подмодули. В этом случае его легко отладить. Но в итоге сами изменения вы не сольете — на уровне мерж-реквеста сторонняя команда, чей модуль вы трогали, может потребовать от вас привести код в соответствие с их правилами.
npm git подмодули
Возможность повторного использования Черновая нарезка функционала
Произвольно вложенные зависимости Плоская структура
Кроссплатформенная разработка Разработка с любым количеством модулей

single-spa

single-spa — это, по сути, фреймворк, который объединяет другие фреймворки. Невероятно мощная технология, за которой скрывается огромное количество нюансов — тема для отдельной статьи.

Схема аналогична iframe, но загрузка МФ теперь осуществляется через нативный импорт + importmap или через Systemjs, если нужны полифиллы.

🍇 Микрофронтенд: что это такое и зачем он нужен?

В отличие от всех методов организации МФ, этот очень заточен под объединение разных фреймворков под себя. Но стоит предостеречь от использования технологий ради самих технологий. Если есть возможность обойтись одним стеком, нужно его использовать. Разработка может быть навсегда обременена поддержанием технически сложного проекта и исправлением любых ошибок из-за побочных эффектов различных приложений. Пользователь может испытывать дискомфорт, т. к. количество кода для загрузки в клиент будет увеличено (ядра разных фреймворков под разные куски функционала + ядро ​​самого синглспа и его плагинов).

Плюсы Минусы
Независимое развертывание Большая документация, которая все же не охватывает все случаи
Фреймворк-агностик Трудности с SEO
Мощный интерфейс командной строки

Webpack 5 Module Federation

Плагин webpack 5, разработанный специально для создания МФ. Перспективная технология: небольшой плагин сборки для более корректной сборки и динамического импорта во время выполнения.

Схема почти один в один повторяет singlespa, но теперь для загрузки МФ используется динамический импорт

🍇 Микрофронтенд: что это такое и зачем он нужен?
Плюсы Минусы
Независимое развертывание Низкий уровень
Легкая реализация
Совместимость с SSR

Как выбрать, что использовать в вашем случае?

Давайте посмотрим, что можно применять и для чего:

  • iframe - единая вставка для комбинации несочетаемого;
  • веб-компоненты — когда нужен небольшой сквозной функционал без привязки к фреймворку, как корпоративный ui-kit;
  • пакеты npm — если есть возможность повторного использования между проектами и/или вам нужна проверка типов во время сборки;
  • git submodules — когда нужно грубо порубить проект и распределить зоны ответственности;
  • single-spa — когда есть острая необходимость комбинировать несколько фреймворков до бесконечности, желательно без SSR;
  • модуль-федерация — все остальные сценарии использования МФ при условии единства стека.

Каждый подход хорош по-своему и всему должно быть свое место. Прежде чем переходить на МФ, советуем подумать, а действительно ли это вам нужно. Какой бы подход ни был выбран, он неизбежно что-то усложнит на уровне разработки, CI/CD или производительности. Если есть возможности остаться на едином стеке и монолитном приложении, с удовольствием этим воспользуюсь.

И конечно же, не забывайте о пользователях. В конечном итоге они скачивают все подключенные фреймворки и терпят возможные баги от некорректной интеграции МФ в разные куски функционала. Бизнесу, в свою очередь, придется платить за внедрение и поддержку всего этого.

Источники

МЕРОПРИЯТИЯ

Комментарии

ВАКАНСИИ

Добавить вакансию
Java Team Lead
Москва, по итогам собеседования
Go-разработчик
по итогам собеседования

ЛУЧШИЕ СТАТЬИ ПО ТЕМЕ