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

Привет народ! В этом посте мы узнаем, как обрабатывать сложные и большие приложения с помощью микроинтерфейсов. Как следует из названия, цель состоит в том, чтобы изолировать приложение от более мелких приложений и интегрировать их все в окончательное требование. Звучит круто ? Это. Давайте рассмотрим часть как*.

Микрофронтенды — это небольшие автономные веб-приложения, которые используют общую кодовую базу внешнего интерфейса. Они общаются друг с другом с помощью общего API. Внешний интерфейс приложения разбивается на отдельные, слабо связанные «микроприложения», которые можно создавать, тестировать и развертывать независимо друг от друга.

*хорошо иметь базовые знания о реализации webpack.

Необходимость и преимущества

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

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

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

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

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

Узнайте больше здесь:



Архитектура

Интеграции

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

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

Что касается интеграции каждого микроприложения в хост-приложение, мы могли бы использовать следующие технические подходы:

  • Интеграция на стороне клиента. Браузер выполняет интеграцию.
  • Интеграция на стороне сервера. Сервер выполняет интеграцию.
  • Интеграция во время сборки. Интеграция выполняется во время компиляции.

Такие инструменты, как Модуль федерации Webpack, могут помочь нам в работе с нашими микро-интерфейсами.

Webpack — это сборщик кода для javascript. Мы можем упростить его использование, как показано ниже:

К концу 2020 года Зак Джексон выпустил свой шедевр «Module Federation» в виде плагина в Webpack 5. Плагин Module Federation вывел мир микро-фронтендов на совершенно новый уровень.

Реализация

Мы будем реализовывать интеграцию на стороне клиента или во время выполнения в нашем примере реализации электронной коммерции. Эта интеграция имеет следующие преимущества:
1. ProductList можно развернуть независимо в любое время.
2. Можно развернуть разные версии ProductList, и контейнер может решить, какую из них использовать.

Сложная или более трудоемкая часть — это инструменты и настройка.

Мы будем использовать возможности федерации модулей, предоставляемые webpack 5. Реализация может быть описана в следующих шагах.

  1. Назначьте одно веб-приложение хостом (контейнером), а другие — удаленными (продукты и корзина).
  2. В Remote переместите применимые функции, чтобы сделать их доступными для других веб-приложений. И эти файлы можно открыть с помощью Module Federation.
  3. В Host импортируйте необходимые функции из Remote

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

Давайте воспользуемся create-react-app и создадим три разных реагирующих приложения, а именно контейнер, корзину и товары. Зависимости в package.json должны выглядеть следующим образом:

Faker используется для создания поддельных данных API для примера приложения.

Мы добавим webpack.config.js в каждую корневую папку, и наша окончательная структура папок должна выглядеть следующим образом:

конфиг webpack для первого изолированного приложения — продукты:

const HtmlWebpackPlugin = require("html-webpack-plugin");
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");

module.exports = {
  mode: "development",
  devServer: {
    port: 8081,
  },
  plugins: [
    new ModuleFederationPlugin({
      name: "products",
      filename: "remoteEntry.js",
      exposes: {
        "./ProductsIndex": "./src/bootstrap",
      },
      shared: ["faker"],
    }),
    new HtmlWebpackPlugin({
      template: "./public/index.html",
    }),
  ],
};

Конфиг webpack для второго изолированного приложения — корзины:

const HtmlWebpackPlugin = require('html-webpack-plugin');
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');

module.exports = {
  mode: 'development',
  devServer: {
    port: 8082,
  },
  plugins: [
    new ModuleFederationPlugin({
      name: 'cart',
      filename: 'remoteEntry.js',
      exposes: {
        './CartShow': './src/bootstrap',
      },
      shared: ['faker'],
    }),
    new HtmlWebpackPlugin({
      template: './public/index.html',
    }),
  ],
};

Конфиг webpack для базового приложения — контейнера:

const HtmlWebpackPlugin = require('html-webpack-plugin');
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');

module.exports = {
  mode: 'development',
  devServer: {
    port: 8080,
  },
  plugins: [
    new ModuleFederationPlugin({
      name: 'container',
      remotes: {
        products: 'products@http://localhost:8081/remoteEntry.js',
        cart: 'cart@http://localhost:8082/remoteEntry.js',
      },
    }),
    new HtmlWebpackPlugin({
      template: './public/index.html',
    }),
  ],
};

Так что же здесь происходит?

Наши изолированные приложения, продукты и корзина работают соответственно на портах 8081 и 8081. Контейнер находится на порту 8080.

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

Теперь контейнер может иметь доступ к изолированным приложениям через свойство имени файла модуля ModuleFederationPlugin в каждом приложении с использованием удаленного свойства, например:

remotes: {
    products: 'products@http://localhost:8081/remoteEntry.js',
    cart: 'cart@http://localhost:8082/remoteEntry.js',
  }

Внутри index.js контейнера мы можем монтировать изолированные приложения как:

import { mount as productsMount } from 'products/ProductsIndex';
import { mount as cartMount } from 'cart/CartShow';

console.log('Container!');

productsMount(document.querySelector('#products-app'));
cartMount(document.querySelector('#cart-app'));

Где products-app и cart-app — это селекторы идентификаторов HTML-элементов, в которые будут смонтированы эти приложения.

Это все для реализации!

Миграция: существующая кодовая база в микроинтерфейс

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

  1. Мы должны убедиться, что используем последнюю версию React с версией выше 17. React v17 и выше будет оснащен Webpack версии 5 или выше, который имеет функции интерфейсов Micro.
  2. Выберите тип интеграции с интерфейсом Micro, который подходит для вашего приложения.
  3. Измените файл webpack.config (главным образом для интеграции во время выполнения) для предоставления доступа и функций удаленного доступа.
  4. Попробуйте создать глобальные службы (такие как аутентификация, уведомление и т. д.) в приложении, специфичные для функциональности или той части, которую вы хотите создать в виде микроинтерфейса.

Даже если в настоящее время вы не используете MFE в своем проекте, рекомендуется попробовать POC или личный проект, основанный на этой концепции.

Спасибо за прочтение!

Создавайте интерфейсы Micro с повторно используемыми компонентами

Инструмент с открытым исходным кодом Bit помогает более чем 250 000 разработчиков создавать приложения с компонентами.

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

Подробнее

Разделите приложения на компоненты, чтобы упростить разработку приложений, и наслаждайтесь наилучшими возможностями для рабочих процессов, которые вы хотите:

Микро-интерфейсы

Система дизайна

Совместное использование кода и повторное использование

Монорепо

Узнать больше: