Концепция микро-фронтенда – это микросервисный подход при разработке клиентской части. В настоящее время есть тенденция создавать мощное и функционально насыщенное веб-приложение, расположенное поверх микросервисной архитектуры. Со временем микро-фронтендовая архитектура становится частью приложения, зачастую ее разрабатывает отдельная команда. Эта архитектура растет, ее становится сложно поддерживать. Возникает так называемый «фронтендовый монолит». Для решения этой проблемы была сформулирована концепция микро-фронтендов.
Команда кросс-функциональна и разрабатывает фичи в сквозном исполнении: от пользовательского интерфейса до базы данных. Микро-фронтенд понятнее монолита и не столь громоздкий. Микро-фронтендовая архитектура такого типа призвана разделить все компоненты приложения на категории в зависимости от их бизнес-составляющей, в масштабах всего стека. В таком случае разработчики фронтенда могут рассчитывать на ту же степень гибкости, тестируемости и скорости разработки, какая привычна для команд с бекенда, работающих с микросервисами.
Как устроен микро-фронтенд?
Стратегии, наилучшие практики и рецепты работы с фронтендом позволяют собрать современное веб-приложение, в разработке которого участвует много команд, которые могут использовать разные JavaScript-фреймворки.
Вот основные концепции, на которых выстроена микро-фронтендовая архитектура
Технологическая независимость
Каждая команда должна выбирать и совершенствовать стек, не координируясь с другими командами. Собственные элементы позволяют скрывать детали реализации, а другим предоставлять нейтральный интерфейс.
Изолированность кода, создаваемого разными командами
Никогда не используйте среду времени исполнения совместно, даже если разные команды работают с одним и тем же фреймворком. Стройте независимое и самодостаточное приложение. Не полагайтесь на разделяемое состояние или глобальные переменные.
Создание командных префиксов
В случаях, когда изоляция пока недостижима изоляция, используйте соглашения об именовании. Создавайте пространства имен для таблиц стилей, локального хранилища данных, событий и куки; так удастся избежать коллизий и пояснить, кто чем владеет.
Нативные возможности браузера предпочтительнее созданных вами API
Для коммуникации не пишите глобальную систему «публикация/подписка», а пользуйтесь событиями браузера. Если будет необходимость создать API для совместной работы нескольких команд, постарайтесь держать его максимально простым.
Обеспечение надежного веб-дизайна
Все фичи должны быть полезными, даже если JavaScript выполнить не удается. Чтобы улучшить воспринимаемую производительность, пользуйтесь универсальным рендерингом и прогрессивными усовершенствованиями.
Каковы наилучшие практики, принятые в микро-фронтенде
Различные практики, при помощи которых реализуется микро-фронтендовая архитектура:
Единый мета-фреймворк для SPA (одностраничных приложений) комбинирует на одной странице сразу несколько приложений без необходимости обновлять страницу; таковы, в частности, React, Vue, Angular, т.д.
Множество одностраничных приложений находятся по разным URL. Для приложений с разделяемой функциональностью нужно использовать компоненты NPM или Bower.
Обособление микро-приложений в Iframes при помощи Windows. API для отправки сообщений и библиотеки нужны для координации. IFrames разделяют API, предоставляемые их родительским окном.
Различные модули должны обмениваться информацией через разделяемую шину событий. Каждый модуль работает с собственным фреймворком, когда обрабатывает входящие и исходящие события.
Библиотеки компонентов, зависящие от стека главного приложения, различные компоненты и разделы приложения разрабатываются как библиотеки, после чего их «требует» главное приложение. Следовательно, главное приложение состоит из разнородных компонентов.
Как взять на вооружение микро-фронтендовую архитектуру?
Вот как перейти на микро-фронтендовую архитектуру и реализовать микросервисное тестирование с применением веб-компонентов:
Интеграция в браузере
Веб-компоненты открывают путь к созданию фрагментов клиентской части, импортированных в веб-приложения. Эти фрагменты можно упаковывать в микросервисы вместе с компонентами серверной части. Создаваемые сервисы полноценно оснащаются как логикой, так и визуальными представлениями, упакованными вместе. При применении такого подхода приложения для клиентской части редуцируются до маршрутизации с принятием решений относительно того, какой набор компонентов будет отображаться, а также до оркестрации событий, происходящих между различными веб-компонентами.
Веб-компоненты
Веб-компоненты обеспечивают создание многоразовых единиц, импортируемых в веб-приложения. Они подобны виджетам, импортируемым на любую веб-страницу. В настоящее время они нативно поддерживаются в браузерах Chrome, Opera и Firefox. Если тот или иной браузер не поддерживает веб-компоненты нативно, совместимость достигается при помощи полифиллов JavaScript. Веб-компоненты состоят из 4 элементов, которые могут использоваться отдельно или вместе -
Собственные элементы
Теневая DOM
Импорты HTML
Шаблоны HTML
Собственные элементы
При помощи собственных элементов (Custom Elements) создаются собственные HTML-теги и элементы. Каждый элемент сопровождается своими CSS-стилями и скриптами. Если нужно создавать собственные теги, применять стили CSS и добавлять поведения, то это делается при помощи скриптов. Единственный требуемый стандарт – ставить дефис во избежание конфликта с новыми HTML-элементами. Например, при создании списка оформляемых заказов, в котором присутствуют как собственные элементы, так и собственные теги, получаются веб-компоненты и обратные вызовы жизненного цикла элементов. Эти обратные вызовы жизненного цикла позволяют определять поведения, специфичные для разработки компонентов. Обратные вызовы жизненного цикла, используемые с собственными элементами, таковы:
CreatedCallback
– определяет поведение, происходящее, когда компонент прошел регистрацию.AttachedCallback
– определяет поведение, происходящее, когда компонент вставлен в DOM.DetachedCallback
– определяет поведение, происходящее, когда компонент отсутствует в DOM.AttributeChangedCallback
- определяет поведение, происходящее, когда добавляется, меняется или удаляется атрибут.
Наилучший пример с собственными элементами:
class CheckoutBasket extends HTMLElement {
constructer (){...} is created
connectedCallback (){...} attached to DOM
attributeChangedCallback (attr , oldVal , newVal) someone changed an attribute
disconnecteCallback () {...} removed from DOM, cleanup events that have been registered
}
Собственные элементы, применяемые по умолчанию - stencil, svelte, SkateJS, AngularElements, hyperHTML, т.д.
Теневая DOM
Теневая DOM от основной DOM – это API, сочетающий HTML, CSS и JavaScript внутри веб-компонента. Когда они находятся внутри компонента, они отделены от основной объектной модели документа. Такое отделение напоминает следующую ситуацию: пользователь занимается созданием сервисов API, а потребитель сервиса API ничего не знает о его внутреннем строении, так как все, что важно для пользователя – это запросы к API. У такого сервиса нет никакого доступа к внешнему миру, за исключением запрашивания API других сервисов. Подобные возможности были представлены и в веб-компонентах. Обращения к их внутреннему поведению извне не происходит, ха исключением случаев, когда это разрешено преднамеренно. Аналогично, теневая DOM никак не затрагивает основную DOM того документа, в котором находятся компоненты. Основной способ связи между веб-компонентами – это срабатывание событий.
HTML-импорты
Для веб-компонентов HTML-импорты являются механизмом упаковки. HTML-импорты сообщают DOM, где находится веб-компонент. В контексте микросервисов в импорте удаленного местоположения сервиса содержится тот компонент, который нужно использовать. HTML-импорты позволяют переиспользовать и включать HTML-документы посредством других HTML-документов. Заранее заданные компоненты, действующие в качестве HTML-импортов, где каждый из них включает свои собственные стили и скрипты, на самом высоком уровне решают, что HTML-импорт представляет в DOM в настоящий момент, а импортированный документ обрабатывает все прочие вещи.
Оболочка – это наиболее внешняя обертка, состоящая из контейнера для компонента и палитры компонентов. В ее состав должны входить контроллеры или представления, позволяющие пользователю оперировать компонентами.
Контейнер – это фактическая корневая точка, куда должен внедряться HTML-код вложенных приложений. Для всех вложенных приложений у него должна быть единая точка входа.
Палитра компонентов позволяет управлять вложенными приложениями, активными в настоящий момент.
HTML-шаблоны
HTML-шаблон – это элемент, содержащий содержимое с клиентской части, которое не отображается при загрузке страницы. Давайте попробуем понять реализацию микро-фронтендовой архитектуры на примере следующего приложения, написанного на React.Js. Хорошо, когда веб-приложения разрабатываются независимо друг от друга, чтобы при изменении некоторого элемента он не блокировал и не повреждал другие. Вот почему в этом примере новое приложение React должно собираться, запускаться и развертываться отдельно, а другие приложения, с которыми ему придется обмениваться информацией – расценивать как сервисы. Так, в нижеприведенном примере создается заголовок для веб-страницы. Здесь используется React.js. Это новомодная вещь. Давайте воспользуемся create-react-app
для быстрой начальной загрузки:
npm install -g create-react-app
create-react-app head
cd head/
npm start
Теперь смотрите, как быстро у нас получится добавить рендеринг на стороне сервера. Позже эта функция поможет нам при поисковой оптимизации и улучшении производительности. Проще прикрепить это в самом начале.
Затем создадим файл под названием server.js в корне проекта; он будет запускать сервер express, а также сделаем серверный рендеринг react:
const path = require('path');
const fs = require('fs');
const express = require('express');
const React = require('react');
const App = require('./transpiled/App.js').default;
const { renderToString } = require('react-dom/server');
const server = express();
server.get('/', (req, res) => {
const htmlPath = path.resolve(__dirname, 'build', 'index.html');
fs.readFile(htmlPath, 'utf8', (err, html) => {
const rootElem = '
const renderedApp = renderToString(React.createElement(App, null)); res.send(html.replace(rootElem, rootElem + renderedApp)); server.use(express.static(‘build’));const port = process.env.PORT || 8080;server.listen(port, () => { console.log(`App listening on port ${port}`); });
Этот скрипт укореняется там, где находится элемент react (App), отображает его в строку и отправляет в HTML, прежде, чем выдать пользователю. Позже React поднимется на базе этого уже отображенного компонента. Но он работает на NodeJS, а Node JS не понимает JSX или других сравнительно новых видов синтаксиса, например, import, поэтому для транспиляции этого кода перед запуском на сервере использовался babel:
npm install --dev babel-cli babel-preset-es2015
Добавляем две задачи в раздел со скриптами в package.json, чтобы это запустить:
"transpile": "NODE_ENV=production babel src --out-dir transpiled --presets es2015,react-app",
"start:prod": "NODE_ENV=production node server.js"
Вот и все. Теперь запускаем заголовок при помощи:
npm run build
npm run transpile
npm run start:prod
Почему микро-фронтенды так важны?
В наше время, когда появляются все новые веб-приложения, клиентская часть все укрупняется, а важность серверной части снижается. Большая часть кода относится к микро-фронтендовой архитектуре. А монолитный подход с большими веб-приложениями не работает. Должен быть инструмент для разбиения такого монолита на сравнительно мелкие модули, действующие независимо друг от друга. Решение для этой проблемы – микросервисное устройство фронтенда. Код клиентской части пишется исключительно на чистом JavaScript и с применением любых javascript-фреймворков, с которых или на которые осуществлялась миграция.
Каковы достоинства микро-фронтендовой архитектуры?
Что ни день - изобретается новая технология для JavaScript, и число этих технологий растет как снежный ком. Иногда это может напрягать, поскольку у каждой JavaScript-технологии есть свои достоинства и недостатки. А при выборе технологии всегда стремишься к максимальной пользе и минимальным рискам. Рекомендуемые практики микро-фронтенда предполагают, что разные технологии должны применяться для разработки разных сервисов. Вот лишь некоторые достоинства такой архитектуры:
Поддержка изоляции кода и стиля. Каждая команда разработчиков может выбрать себе технологию по вкусу. Как разработка, так и развертывание осуществляется очень быстро.
Способствует непрерывному развертыванию
Тестирование сильно упрощается; когда нужно проверить небольшое изменение, не приходится затрагивать все приложение.
Реновация фронтенда – упрощается косметическое обновление
Повышенная надежность и удобство в поддержке
Заключительные замечания
Вы убедитесь, что в микро-фронтендовой архитектуре как ядро кода, так и интеграция устроены невероятно просто. Одна из критически важных проблем – стандартизация принципов UI/UX. Универсальное решение – опираться на стилевое руководство, среди прочего – на Material Design, Bootstrap. Чтобы все работало гладко, нужно наладить коммуникацию в команде, разработать стандарты и правила, минимизировать трения между разными командами. Все эти практики, рекомендуемые в микро-фронтендовой архитектуре, помогают решить важнейшую проблему: масштабируемость. Бывают приложения, которые начинают разбухать, а с таким ростом сопряжены многочисленные проблемы и конфликты. Если разделить код между командами и правильно организовать его «логистику» - придет качество, будут учтены технологические тренды, а мир обогатится новыми быстрыми решениями.
Комментарии (13)
nin-jin
30.09.2021 23:06-1ПСБанк недавно проводил хакатон на тему микрофронтендов. Так мы там демонстрировали подход $mol на эту тему. И не смотря на то, что $mol не был рекомендуемой технологией, нам удалось попасть в тройку финалистов. Просто потому, что мы смогли за пару дней сделать больше и качественнее в свободное от безделья время. Гляньте, наш питч - это кардинально иной подход, вобравший лучшее из обоих миров:
merrick_krg
01.10.2021 02:02+10Что мне нравится в микрофронтенде, что любой аргумент который используется как достоинство, можно использовать как и недостаток)
Работал и видел несколько очень крупных проектов, от 1 до 3млн строк, прекрасно масштабировались и работали. И я честно не представляю какого масштаба был бы хаос в этих проектах будь они микрофронтовыми.
Особенно классно, когда ты где то за городом или в метро, тебе очень срочно нужна информация, а вместо этого грузится angular и вроде бы ты даже его грузил, но черт, он другой версии….
А править баги связанные с ядром микрофронтов это просто адовый труд.
Я вижу только пару причин использовать микрофронтенд:
переезд на другую технологию, когда требуется итеративный переход.
Экономия на ресурсах других отделов, это касается именно поставки отдельных модулей/приложений. Если мы поставляем физически одно приложение из ста, то и тестировать можно одно из ста, но с этим прекрасно справляется и микросервисный монолит.
Технологию настолько наводящую хаос в проекте не встречал со времён редакса)
Холивар опен)
i360u
01.10.2021 08:52+1Микрофрентенды - это подход адекватный лишь в некоторых ситуациях, он точно не для всех. Поэтому, все зависит от конкретной ситуации, решение тут точно не стоит принимать на волне хайпа. Частным случаем применимости можно считать виджеты сторонних сервисов: на мой взгляд, это хороший пример того, когда это работает и вообще понятно зачем. Однако, виджетостроение - это особое искусство, где планка требований к разработчикам заметно выше.
MentalBlood
01.10.2021 09:31А что не так с редаксом? Вроде ж его так активно продвигали и использовали, причем создавалось ощущение, что он именно про наведение порядка (а не про магию [хаоса])
markelov69
01.10.2021 12:11+4А что не так с редаксом?
Проблемы:
— Иммутабильность.
— Тонны абсолютно лишнего кода.
— Гнусная производительность (особое «спасибо» иммутабильности).
— Не удобно читать/писать данные.
Преимущества:
— Отсутствуют.
Поэтому все адекватные люди уже давным давно используют MobX.
Sm1le291
01.10.2021 09:36+1Работал и видел несколько очень крупных проектов, от 1 до 3млн строк
каждый раз улыбаюсь, когда люди оценивают сложность проекта по количеству строк)merrick_krg
01.10.2021 15:02+2А как по другому формализовать сложность? В основном это понятие субъективное, а количество строк кода как минимум какой то объективный показатель, на основе которого можно понять порядок потраченных ресурсов.
artchalet
01.10.2021 12:51Холивар опен)
Вроде на хабре в основном +- согласятся с вами. Насчет микросервисов хайпа было много, но в реальные проекты очень немного перешло.
merrick_krg
01.10.2021 15:03Возможно у меня контекст такой, но каждый второй проект в сфере финтеха или экосистем с которым я сталкиваюсь, сейчас либо переходит на микрофронт, либо инвестирует в изучение этих переходов.
DmitryKazakov8
01.10.2021 15:35Когда проект завален деньгами и берут всех разработчиков подряд, достигая заявленных целей по количеству персонала — тогда да, микрофронт — отличное занятие для большей части этих программистов. Тоже в финтехе наблюдал и немного участвовал в подобном, когда вместо продуктовой разработки много людей занимаются развитием протоколов подключения и общения разнородных баз кода на одной странице, поддержкой аналогичных по функционалу библиотек компонентов, решением коллизий и взаимовлияния кода, апдейтом в десятках репозиториев дублирующегося кода (подключения шрифтов, к примеру, либо коннекторов к руту), cli-инструментами для фетча нескольких реп и управления их локальными версиями, решением проблем версионирования/выкатки/интеграционного тестирования/откатов при деплое, подключением серверного рендеринга и строковой склейкой одной страницы из нескольких частей...
И, разумеется, все это значительно влияет на производительность приложения и его размер + скорость поставки фич. Через полгода-год это с большой вероятностью приходит в холд по бизнес-фичам со всеми вытекающими.
Так что какой холивар — и так понятно, что микрофронты для очень узкого круга проектов (этап миграции либо виджеты), нишевая технология. А при применении в качестве основной архитектуры недостатков намного больше, чем преимуществ.
atomic1989
02.10.2021 18:28Пробовали что-то из аля микрофронтенда во времена, когда и не пахло этой темой, на базе SharePoint. Воспоминания как про срочную службу в армии). Рано еще переходить, инфраструктура окружения не готова
i360u
01.10.2021 08:56+2Статья - ужасна, куча ошибок и неточностей как в примерах кода так и в описании технологий. Я понимаю конечно, что перевод, но тут, видимо, и сам исходник - треш.
raamid
Медитировал над рисунком, но совершенно ничего не понял. К сожалению, текст никак не связан с рисунком, причем в оригинальной статье тоже текст не связан с рисунком. Может быть кто-то понимает о чем там идет речь?