Создание сайтов в Москве. Руководство для начинающих по архитектуре Micro Frontend

 
 

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

Текущее состояние веб-приложений

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

Типичный поток приложений SPA следует стандартным шагам:

пользователь посещает веб-приложение

браузер запрашивает JavaScript и CSS

приложение JavaScript запускается и добавляет начальный контент в документ браузера

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

приложение переписывает части документа браузера, чтобы отразить изменения

В большинстве случаев для достижения вышеуказанного используется фреймворк JavaScript. В таких фреймворках, как React, Vue или Angular, есть шаблоны и лучшие практики, помогающие создавать SPA. Например, React — это очень интуитивно понятная структура, использующая JSX для рендеринга контента на основе изменений пользователя и данных. Давайте рассмотрим базовый пример ниже:

//App.js

import React from «react»;

import «. /styles.css»;

const App = () => {

return (

Hello I’m a SPA 👋

) ;

}

export default App;

Это наше основное приложение. Он отображает простой вид:

import React from «react»;

import ReactDOM from «react-dom»;

import App from «. /App»;

const rootElement = document.getElementById («root») ;

ReactDOM.render (

,

rootElement

) ;

Затем мы запускаем приложение, визуализируя приложение React в DOM браузера. Это просто основа СПА. Отсюда мы могли бы добавить больше функций, таких как маршрутизация и общие компоненты.

SPA — основа современной разработки, но они не идеальны. СПА имеет много недостатков.

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

Сложность фреймворка — еще один недостаток. Как упоминалось ранее, существует множество фреймворков, которые могут предоставить возможности SPA и позволить вам создать надежный SPA, но каждый из них нацелен на разные потребности, и понять, какой из них выбрать, может быть сложно.

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

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

Итак, каково решение всех этих проблем? Микро интерфейсы!

Что такое микро-фронтенд?

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

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

Макет пиццерии SPA

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

SPA разбит на микрофронтенды

Все микрофронтенды начинаются с хост-контейнера. Это основное приложение, которое скрепляет все части вместе. Это будет основной файл JavaScript, который отправляется пользователю при посещении приложения. Затем мы переходим к собственно микроинтерфейсам — списку продуктов и интерфейсу корзины. Они могут быть локально отделены от основного хоста и доставлены в виде микроинтерфейса.

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

Как создать микро-интерфейс?

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

Полноценное рабочее приложение микро-фронтенда webpack можно найти здесь.

Домашний контейнер

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

// packages/home/webpack.config.js

const ModuleFederationPlugin = require («webpack/lib/container/ModuleFederationPlugin») ;

module.exports = {

...

plugins: [

new ModuleFederationPlugin ({

name: «home»,

library: { type: «var», name: «home» },

filename: «remoteEntry.js»,

remotes: {

«mf-products»: «products»,

«mf-basket»: «basket»,

},

exposes: {},

shared: require («. /package.json»).dependencies,

}),

new HtmlWebPackPlugin ({

template: «. /src/index.html»,

}),

],

};

Примечание: посмотреть webpack.config.jsфайл на GitHub можно здесь.

Здесь мы даем модулю имя «дом», так как это контейнер, содержащий все внешние интерфейсы. Затем мы предоставляем сведения о библиотеке, так как контейнер также может быть микроинтерфейсом, поэтому мы объявляем сведения о нем, такие как его тип, который в данном случае является файлом var. Тип определяет тип модуля веб-пакета. varобъявляет, что модуль соответствует стандарту ES2015.

Затем у нас есть продукты и модули корзины, настроенные как пульты. Позже они будут использоваться при импорте и использовании компонентов. Имя, которое мы даем модулям, будет использоваться при их импорте в приложение («mf-products» и «mf-basket»).

После того, как мы настроим модули, мы можем добавить теги script в основной index.htmlфайл дома, которые будут указывать на размещенные модули. В нашем случае все это выполняется на локальном хосте, но в продакшене это может быть веб-сервер или корзина Amazon S3.

//product list

//basket

Примечание: посмотреть index.htmlфайл на GitHub можно здесь.

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

С помощью using React.lazyмы можем импортировать компоненты, но базовый код будет получен только при рендеринге компонентов. Это означает, что мы можем импортировать компоненты, даже если они не используются пользователем, и условно визуализировать их постфактум. Давайте посмотрим, как мы используем компоненты в действии:

// packages/home/src/src/App.jsx

const Products = React.lazy (() => import («mf-nav/Products»));

const Basket = React.lazy (() => import («mf-basket/Basket»));

Примечание: посмотреть App.jsxфайл на GitHub можно здесь.

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

Товар и корзина

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

// packages/basket/webpack.config.js

const ModuleFederationPlugin = require («webpack/lib/container/ModuleFederationPlugin») ;

module.exports = {

...

plugins: [

new ModuleFederationPlugin ({

name: ‘basket’,

library: {

type: ‘var’, name: ‘basket’

},

filename: ‘remoteEntry.js’,

exposes: {

'. /Basket’: '. /src/Basket’

},

shared: require ('. /package.json’).dependencies

})

],

};

Примечание: посмотреть webpack.config.jsфайл на GitHub можно здесь.

Мы даем модулю имя, которое будет продуктами или корзиной и информацией о библиотеке, а затем fileName— в данном случае удаленный вход. Это стандарт для веб-пакетов, но это может быть что угодно, например кодовое имя продукта или имя модуля. Это будет файл, который генерирует веб-пакет и который будет размещен для ссылки на домашний контейнер. Используя имя файла remoteEntry, полный URL-адрес модуля будет http://myserver.com/remoteEntry.js. Затем мы определяем параметр разоблачения. Это определяет, что модуль экспортирует. В нашем случае это просто файл корзины или товаров, который является нашим компонентом. Однако это могут быть несколько компонентов или разные ресурсы.

И, наконец, в домашнем контейнере вот как вы можете использовать эти компоненты:

// packages/home/src/src/App.jsx

<React.Suspense fallback={

...loading product list
}>

 

<ProductList

onBuyItem={onBuyItem}

/>

{

selected.length > 0 &&

<React.Suspense fallback={

...loading basket
}>

<Basket

items={selected}

onClear={ () => setSelected ([]) }

/>

}

Примечание: посмотреть Product and Basket usageфайл на GitHub можно здесь.

Зависимости

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

Вы можете настроить общий параметр двумя способами. Первый способ — это список известных общих модулей Node, которыми вы хотите поделиться. Другой вариант — передать список зависимостей модулей из собственного JSON-файла пакета. Это позволит разделить все зависимости, и во время выполнения webpack определит, что ему нужно. Например, когда корзина будет импортирована, веб-пакет сможет проверить, что ему нужно, и были ли его зависимости разделены. Если корзина использует Lodash, а дом — нет, она получит зависимость Lodash из модуля корзин. Если в доме уже есть Lodash, он не будет загружен.

Недостатки

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

Дублированная логика зависимостей. Как упоминалось в разделе о зависимостях, webpack может обрабатывать для нас общие модули Node. Но что происходит, когда одна команда использует Lodash для своей функциональной логики, а другая использует Ramda? Теперь мы поставляем две библиотеки функционального программирования для достижения того же результата.

Сложность проектирования, развертывания и тестирования. Теперь, когда наше приложение динамически загружает контент, может быть сложнее получить полную картину всего приложения. Убедиться, что вы отслеживаете все микрофронтенды, — задача сама по себе. Развертывание может стать более рискованным, так как вы не уверены на 100%, что именно загружается в приложение во время выполнения. Это приводит к более жестким испытаниям. Каждый интерфейс можно протестировать изолированно, но для того, чтобы убедиться, что приложение работает для конечного пользователя, необходимо провести полное тестирование в реальных условиях.

Стандарты. Теперь, когда приложение разбито на более мелкие части, может быть сложно заставить всех разработчиков работать по одним и тем же стандартам. Некоторые команды могут продвинуться дальше, чем другие, и либо улучшить, либо ухудшить качество кода. Удержание всех на одной странице важно для обеспечения высококачественного взаимодействия с пользователем.

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

Вывод

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

3D-печать5GABC-анализAndroidAppleAppStoreAsusCall-центрChatGPTCRMDellDNSDrupalExcelFacebookFMCGGoogleHuaweiInstagramiPhoneLinkedInLinuxMagentoMicrosoftNvidiaOpenCartPlayStationPOS материалPPC-специалистRuTubeSamsungSEO-услугиSMMSnapchatSonyStarlinkTikTokTwitterUbuntuUp-saleViasatVPNWhatsAppWindowsWordPressXiaomiYouTubeZoomАвдеевкаАктивные продажиАкцияАлександровск ЛНРАлмазнаяАлчевскАмвросиевкаАнализ конкурентовАнализ продажАнтимерчандайзингАнтрацитАртемовскАртемовск ЛНРАссортиментная политикаБелгородБелицкоеБелозерскоеБердянскБизнес-идеи (стартапы)БрендБрянкаБукингВахрушевоВендорВидеоВикипедияВирусная рекламаВирусный маркетингВладивостокВнутренние продажиВнутренний маркетингВолгоградВолновахаВоронежГорловкаГорнякГорскоеДебальцевоДебиторкаДебиторская задолженностьДезинтермедитацияДзержинскДивизионная система управленияДизайнДимитровДирект-маркетингДисконтДистрибьюторДистрибьюцияДобропольеДокучаевскДоменДружковкаЕкатеринбургЕнакиевоЖдановкаЗапорожьеЗимогорьеЗолотоеЗоринскЗугрэсИжевскИловайскИрминоКазаньКалининградКировскКировскоеКомсомольскоеКонстантиновкаКонтент-маркетингКонтент-планКопирайтингКраматорскКрасноармейскКрасногоровкаКраснодарКраснодонКраснопартизанскКрасный ЛиманКрасный ЛучКременнаяКураховоКурскЛисичанскЛуганскЛутугиноМакеевкаМариупольМаркетингМаркетинговая информацияМаркетинговые исследованияМаркетинговый каналМаркетинг услугМаркетологМарьинкаМедиаМелекиноМелитопольМенеджментМерчандайзерМерчандайзингМиусинскМолодогвардейскМоскваМоспиноНижний НовгородНиколаевНиколаевкаНишевой маркетингНовоазовскНовогродовкаНоводружескНовосибирскНумерическая дистрибьюцияОдессаОмскОтдел маркетингаПартизанский маркетингПервомайскПеревальскПетровскоеПлата за кликПоисковая оптимизацияПопаснаяПравило ПаретоПривольеПрогнозирование продажПродвижение сайтов в ДонецкеПроизводство видеоПромоПромоушнПрямой маркетингРабота для маркетологаРабота для студентаРазработка приложенийРаспродажаРегиональные продажиРекламаРеклама на асфальтеРемаркетингРетро-бонусРибейтРитейлРовенькиРодинскоеРостов-на-ДонуРубежноеСамараСанкт-ПетербургСаратовСватовоСвердловскСветлодарскСвятогорскСевастопольСеверодонецкСеверскСедовоСейлз промоушнСелидовоСимферопольСинергияСколковоСлавянскСнежноеСоздание сайтов в ДонецкеСоледарСоциальные сетиСочиСтаробельскСтаробешевоСтахановСтимулирование сбытаСуходольскСчастьеТелемаркетингТельмановоТираспольТорговый представительТорезТрейд маркетингТрейд промоушнТюменьУглегорскУгледарУкраинскХабаровскХарцызскХерсонХостингЦелевая аудиторияЦифровой маркетингЧасов ЯрЧелябинскШахтерскЮжно-СахалинскЮнокоммунаровскЯндексЯсиноватая