Вокруг микрофронтендов было много разговоров и шумихи.
С https://micro-frontends.org/ системы Microfrontend
Методы, стратегии и рецепты создания современного веб-приложения с участием нескольких команд, которые могут выпускать функции независимо друг от друга.
Основная идея состоит в том, чтобы распространить идею микросервисов на разработку внешнего интерфейса, с помощью которой систему можно разделить на команды, владеющие комплексной системой, и независимо доставлять внешние приложения, чтобы составить единое целое.
Простая иллюстрация, объясняющая эту идею, показана ниже:
Микросервисы с интерфейсом Monolith
Микросервисы с Micro Frontend
Микрофронтенды приносят такие же преимущества, как производительность, инкрементальные обновления, несвязанные кодовые базы, независимые развертывания, автономные команды для фронтенд-инжиниринга, как микросервисы привносят в бэкэнд-сервисы.
Теперь команды и пользовательский интерфейс можно разбить на более мелкие группы, как показано на рисунках, но проблема заключается в интеграции и предоставлении пользователям единого опыта, и всегда будут случаи, когда интерфейсы или компоненты интерфейса будут конфликтовать, поскольку компоненты пользовательского интерфейса могут легко расширяться. кросс-страницы/домены.
Уже есть несколько архитектур, которые используются и предлагаются для достижения архитектуры микрофронтенда. В посте Кэма Джексона о Мартине Фаулере есть несколько хороших подходов.
Давайте посмотрим, как наше отношение к микрофронтендам в Cloudfactory влияет на организацию страниц.
Микрофронтенды в действии
Там может быть много перестановок и комбинаций. Есть даже реализации микрофронтендов, которые могут запускать мультифреймворковые компоненты на той же странице Подробнее об этом. Тот, что показан на рисунке, довольно прост, когда команды организованы в рамках бизнес-доменов, а интерфейсы, специфичные для домена, выходят за границы (обращенных к пользователю) интерфейсов приложений. Эти компоненты предметной области могут отображаться в любом пользовательском интерфейсе, но они должны вести себя по-разному и поддерживаться отдельно.
Мы видели подобную организацию в интерфейсе консоли AWS и некоторых интерфейсах Facebook.
Альтернативная реализация для создания большого единого SPA через интеграцию во время выполнения с помощью JavaScript задокументирована и прекрасно реализована на https://microfrontends.com/ и https://martinfowler.com/articles/micro-frontends.html. #Время выполненияIntegrationViaJavascript»
Вместо того, чтобы полагаться на систему интеграции во время выполнения или сложные фреймворки, мы решили изменить несколько конфигураций в процессе сборки и использовать некоторые старые приемы. Наша цель состояла в том, чтобы позволить командам иметь архитектуру микрофронтенда, но не обременять систему еще одной системой для управления самим микрофронтендом. Технически это означает, что у нас нет загрузочного слоя или любого другого сервиса, обслуживающего манифесты активов.
Решение использует React с Typescript и Webpack с набором модулей ESNext. Эта комбинация позволяет нам создавать чрезвычайно оптимизированные несколько приложений без увеличения размера пакета и использовать все преимущества разделения кода и ленивой загрузки.
В сети уже есть большое количество статей о разделении кода React и ленивой загрузке, поэтому я опускаю эти подробности в этом посте.
Решение работает для сценария, в котором у нас есть большое приложение, достаточно большое, чтобы его нельзя было содержать как одностраничное приложение, поэтому оно разделено на несколько страниц SPA или связанных страниц. И несколько команд, работающих вместе, создают небольшие микрокомпоненты на странице.
Концептуальная идея
Идея высокого уровня состоит в том, чтобы экспортировать компоненты в виде модулей ESNext, которые можно легко повторно использовать через интерфейсы через CDN и лениво загружать, когда это применимо. Этот тип интеграции не нов, и мы видели это со времен плагинов и виджетов jQuery.
Для любых общих компонентов и интерфейсов мы создаем модули узла и с конфигурацией машинописного текста module
, установленной в esnext
, и с правильно установленной конфигурацией веб-пакета output.library
, мы получаем модули для работы во время выполнения, загружаемого через CDN. Когда для параметра publicPath
веб-пакета задан путь CDN, выплескивание кода и ленивый/задумчивый React работают хорошо. Нам нужно только знать основную точку входа основного файла модуля, которую можно сделать предсказуемой, если следовать стандартному общекорпоративному соглашению.
Образец tsconfig
{
"compilerOptions": {
"lib": ["dom", "es2015", "es2016"],
"module": "esnext",
"moduleResolution": "node",
"target": "es5",
"jsx": "react",
...
}
}
Пример конфигурации веб-пакета
const version = `${require('./package.json').version}`;
//...
module.exports = {
entry: [
// ...
],
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist', version),
library: ['MFE', 'SHC'],
publicPath: `https://cdn/path/shared-components/dist/${version}/`,
// ...
},
// ...
}
Мы получаем экспортированные модули в глобальном MFE.SHC
объекте, и с правильным набором publicPath
с динамически вычисляемым version
это упрощает создание версионированных артефактов.
Мы придерживаемся семантического управления версиями, поэтому игнорируем версии патчей, поэтому 1.2.1
, 1.2.2
.. 1.2.9
объединяются в 1.2.x
. Это также дает нам возможность вносить изменения в интерфейс без необходимости повторного развертывания определенных страниц. Мы также можем игнорировать младшую версию и всегда использовать 1.x.x
, последнюю основную версию. Это позволит, как показано в примере в демонстрации, команде C публиковать обновление своего интерфейса с любым действием команды A, которая управляет страницей, если они обновляют основную версию.
Затем мы используем веб-пакеты externals
для поиска модулей во время выполнения.
module.exports = {
// ...
externals: {
"react": "MFE.GLB.React",
"react-dom": "MFE.GLB.ReactDOM",
"shared-components": "MFE.SHC"
},
// ...
}
У нас есть глобальные зависимости, экспортированные в один пакет, доступ к которому можно получить по адресу MFE.GLB
.
Упрощенная рабочая демонстрация доступна по адресу https://rohitrox.github.io/microfrontend-esnext-demo/team-a-page/dist/.
Теперь реализация может быть улучшена для поддержки интеграции javascript с микроинтерфейсами во время выполнения. Учитывая развивающееся приложение в cloudfactory, мы чувствовали, что еще не готовы позволить всем микроинтерфейсам автоматически обновляться. Контейнерное приложение/страница и микрофронтенды постоянно меняются, поэтому лучше всего было следить за автоматическими обновлениями на основе основных версий. Если в микроинтерфейсе есть выпуск основной версии, приложение-контейнер должно подтвердить и опубликовать новую версию самого себя, которая будет использовать обновленный микроинтерфейс.
Далее для связи между компонентами микрофронтенда мы используем React props и Custom Events. Существует также ряд доступных библиотек шины событий с открытым исходным кодом.
Для демонстрации я использовал GitHub для всего, включая командные модули и CDN для поиска зависимостей.
Чтобы демонстрация работала со страницами GitHub, я установил publicPath
в конфигурации веб-пакета определенным образом Github.
Страницы индекса жестко закодированы со ссылками на определенный ресурс в CDN. Хотя они жестко закодированы для демонстрации, в нашей реальной системе мы добавили несколько конфигураций в конфигурацию веб-пакета, чтобы позаботиться об этом. Логика заключается в том, чтобы просмотреть зависимости package.json
и автоматически вставить соответствующие элементы script
или link
на страницу индекса с указанной версией.
Исходный код доступен по адресу https://github.com/RohitRox/microfrontend-esnext-demo
Папка была названа так, чтобы имитировать отдельные модули.
О чем не сказано в этом посте
- Таблицы стилей — мы экспортируем базовые стили как общие и используем их через CDN. Чтобы предотвратить переопределение и конфликты, мы запутываем имена классов CSS.
- Несколько версий React — это решение не подходит для этой цели. Все наши микрофронтенды используют совместимые версии React и ReactDOM, поэтому мы используем общую версию. Мы не разрабатывали поверх устаревшего приложения и начинали с нуля, поэтому не сталкивались с этой проблемой.
- SPA-маршрутизация. Маршрутизация React не подробно описана ни в этом посте, ни в демонстрации. Страница контейнера контролируется маршрутизатором, и если микроинтерфейсам необходимо контролировать пути к страницам, они делают это, взаимодействуя с контейнером через реквизиты, обратные вызовы или систему событий.
Ресурсы и дальнейшие исследования:
- Микрофронтенды на martinFowler.com от Кэма Джексона (Статья)
- Реализация микрофронтендов и демонстрация Кэма Джексона (Статья)
- Micro Frontends — Микросервисный подход к современности от Ивана Йовановича (Видео)
- Микрофронтенды — как я создал SPA с помощью Angular и React? Иван Йованович (Статья)
- Архитектура микроинтерфейса Луки Меззалиры, DAZN (видео)
- Микрофронтенды, будущее архитектур фронтенда Луки Меззалиры, DAZN (Статья)
- Создание бессерверных микроинтерфейсов на периферии в AWS re:Invent 2019 (видео) (дополнительно)
Есть комментарии, вопросы или отзывы, давайте свяжемся
Первоначально опубликовано на http://rohitrox.github.io 5 января 2020 г.