Подробно о микрофронтендах: Часть 1 *

Здравствуйте, коллеги-разработчики из блогосферы (или блогосферы?)! В последнее время мало что публиковал, в основном из-за работы над Радостью JavaScript. После этого я хотел вернуться к ведению блога о JavaScript и Интернете и о том, что может быть лучше для начала, чем этот (все еще) формирующийся шаблон под названием микрофронтенды, также известные как MFE.

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

С учетом сказанного, что, черт возьми, такое микрофронтенд? Разве это не очень маленький фрагмент кода JavaScript HTML/JS? Возможно. Но это намного больше. Для одних это архитектурный шаблон, для других — шаблон развертывания. Для меня: и то, и другое. На фундаментальном уровне микрофронтенд — это подход к разработке веб-приложения путем сшивания «небольших», «слабо» связанных компонентов (архитектуры), которые разрабатываются и доставляются независимо (развертывание).

Как и его внутренний аналог, MFE также является обширной темой с разветвлениями на JavaScript-фреймворки, командную/организационную структуру, развертывание и CI/CD, контроль версий и т. д. ), серию сообщений в блогах, которые разбирают каждый аспект этой парадигмы, начиная с очень высокого уровня с точки зрения организации команды. Мы начнем с обсуждения социальных аспектов, которые позволяют приложениям на основе MFE упростить создание больших одностраничных приложений (SPA). MFE позволяют командам быть более продуктивными, независимыми и сфокусированными на разных частях приложения.

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

  1. Как географически устроена организация
  2. Карманы знаний в предметной области распределяются среди членов команды
  3. Ремонтопригодность или уверенность, с которой исправления/улучшения могут быть применены к одной части пользовательского интерфейса, не влияя на остальные.
  4. Необходимость масштабировать одну часть приложения по сравнению с другими

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

Организационная структура

Возможно, вы уже знаете о законе Конвея:

Любая организация, которая проектирует систему (в широком смысле), создаст проект, структура которого является копией коммуникационной структуры организации.

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

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

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

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

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

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

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

Удобство обслуживания

Как и в случае с микросервисами, микрофронтенды превосходят монолитные архитектуры своим подходом без совместного использования (или с очень небольшим количеством общего доступа). Цель состоит в том, чтобы сохранить автономию MFE и установить между ними простые и несвязанные каналы связи.

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

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

Масштаб

Различные части вашего приложения будут иметь разные потребности в производительности. Представьте, что вы имеете дело с форумом или сайтом социальной сети. Компонент, который отображает вложенный набор сообщений и комментариев (с большим количеством вложенных изображений и текста), будет иметь совсем другие потребности в кэшировании, чем, скажем, кнопка входа или компонент профиля пользователя. Комментарии MFE могут потребовать много вызовов API и локального хранилища; тогда как кнопка входа в систему может потребоваться для взаимодействия только с данными сеанса/файла cookie. В монолитной архитектуре становится сложнее реализовать изоляцию и оптимизацию отдельных компонентов.

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

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

Команда решила использовать микрофронтальную архитектуру. В большинстве случаев компании организуют команды так, чтобы одни инженеры начинали создавать серверные API (может быть несколько серверных частей или микросервисов), другие работали над промежуточным программным обеспечением для Интернета, третьи — над логикой и представлением пользовательского интерфейса (несколько MFE или один SPA). пучок). Такое горизонтальное расположение является более традиционным подходом. В этом примере у организации есть инженеры в Бангалоре, Мадриде и Санта-Кларе. Разработчики внешнего интерфейса в Бангалоре самоорганизуются и решают, как работать с каждым MFE-представлением, возможно, используя некоторые фиктивные API-интерфейсы по мере создания реальных API-интерфейсов. В зависимости от того, как разбит сайт, и потребностей в масштабировании, команды из Мадрида и Санта-Клары решат, будет ли это один или несколько микросервисов.

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

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

В качестве альтернативы вы можете применить эту конфигурацию к более вертикальному подходу:

При вертикализации каждая команда берет на себя ответственность не только за создание своих соответствующих приложений MFE с пользовательским интерфейсом, но и за любые необходимые API, промежуточное ПО, сборку и т. д. Такое расположение позволяет командам двигаться еще быстрее, устраняя задержки связи между ними и позволяя им самодостаточный и независимый. Кроме того, если вы решите разложить приложение по ограниченным контекстам, это позволит командам использовать свои знания в предметной области как на интерфейсе, так и на сервере. Конечно, недостатком здесь является то, что это затрудняет обмен знаниями и кодом через общие библиотеки. Это может быть благословением, а не проклятием. Шаблоны micro* действительно способствуют минимальному обмену информацией, допуская некоторый уровень дублирования, когда это практически возможно.

Итак, какой из них я должен выбрать? Это действительно зависит от того, как структурирована ваша компания. В проектах, в которых я участвовал, я видел смесь этих двух. Одна команда создает 80 % MFE, которые составляют SPA с горизонтальными уровнями, и есть одна команда, которая создает оставшиеся 80 % MFE со своим собственным представлением и серверной частью. Независимо от того, как вы решите структурировать команду, ключом к успешному проекту микрофронтендов является установление четких контрактов и руководств по разработке. Я потрачу на них больше времени в следующих постах, но вот некоторые из них, которые я использовал в проектах, частью которых я был:

  1. Ни один MFE не может обращаться к элементам DOM за пределами своей области.
  2. MFE никогда не может полагаться на какое-либо глобальное состояние (например, объект окна).
  3. Если между двумя MFE были отправлены данные или действия, они должны управляться событиями.
  4. Контракты между МФО должны быть максимально простыми. Другими словами, предпочтите простые типы данных (строки, числа, логические значения и т. д.) объектам, определенным пользователем.
  5. … есть много других

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

Заключение

Большая часть информации, которую вы читаете, позиционирует микроинтерфейсы (или микросервисы) как решение, позволяющее упростить разработку всех крупномасштабных веб-приложений. На самом деле я не согласен с этим грандиозным утверждением. Оба имеют свои плюсы и минусы. С социальной точки зрения, которую мы рассмотрели здесь, я думаю, что микрофронтенды определенно помогают, когда ваша команда не находится в одном месте. Это также помогает, если разным командам, возможно, с разными технологическими стеками, необходимо интегрировать свои пользовательские интерфейсы в единый унифицированный SPA. Это позволяет этим командам продолжать работать продуктивно и фокусироваться на своих текущих задачах, не прибегая к новым технологиям только для того, чтобы соответствовать остальным. Команды могут продолжать использовать лучший инструмент для работы. Например, одно приложение может иметь MFE, которые считывают данные с помощью RESTful API, смешанные с MFE, использующим GraphQL, и другие, которые просто используют локальное хранилище. Все это может сосуществовать в одном приложении, но вам не нужно разрабатывать, тестировать и доставлять все сразу каждый раз.

Такие компании, как Amazon, у которых есть гигантские взаимосвязанные веб-приложения, могут масштабироваться до предела благодаря шаблону микроинтерфейса. Под капотом веб-приложение Amazon представляет собой конфломерат из множества микрофронтендов, сшитых вместе и подключенных/отключенных в разное время. Тем не менее, с точки зрения пользователя, все выглядит так, как будто все это исходит из одного связанного SPA — и это цель этого шаблона. Если быть до конца честным, независимо от того, есть ли у вас размер Amazon или нет, я больше не вижу смысла возвращаться к монолитному приложению, независимо от социальной структуры вашей организации. Мы еще не обсуждали какие-либо технические аспекты, но как только мы до них доберемся, я надеюсь, что вы так же убеждены, как и я.

В общем, причины, по которым (я думаю) вы должны использовать этот шаблон для больших сайтов, таковы:

  1. Меньшие кодовые базы, по которым проще ориентироваться и понимать, приведут к меньшим обновлениям кода, которые будут запускаться независимо друг от друга.
  2. Значительно снижая вероятность непреднамеренного нарушения работы других частей приложения из-за общего состояния, команды чувствуют себя намного увереннее в качестве своего кода.
  3. Помогает командам работать быстрее и оставаться максимально сосредоточенными на своей области знаний
  4. Продвигайте демократизированный пользовательский интерфейс, где каждая команда MFE может собраться вместе, чтобы согласовать общую систему дизайна.

Что впереди

В этом посте мы обсудили MFE с более социальной точки зрения. В следующем посте мы начнем погружаться в другие архитектурные проблемы, обсудив различные шаблоны интеграции и коммуникации, такие как: рендеринг на стороне сервера (SSR), рендеринг на стороне клиента (CSR) и включения на стороне периферии (ESI). ). После этого мы коснемся таких тем, как управление исходным кодом, создание конвейеров, фреймворки MFE с открытым исходным кодом, веб-компоненты, Shadow DOM, ShadowRealm, карты импорта и т. д. Это может показаться немного неструктурированным в форме блогов, но, возможно, все когда-нибудь это может быть объединено в книгу… кто знает?

Ресурсы

  1. https://martinfowler.com/articles/micro-frontends.html
  2. https://www.n-ix.com/micro-frontends/
  3. https://www.manning.com/books/micro-frontends-in-action