Мікрофронтенди з Module Federation: shared-залежності та CI/CD

Ви запускаєте кілька React-застосунків — каталог, кошик, особистий кабінет. Кожен збирається у свій бандл, і раптом виявляєте, що React дублюється, а розмір завантаження зростає. Нещодавно на проекті з вісьмома мікрофронтендами ми зіткнулися з тим, що підсумковий бандл користувача становив 2.4 MB. B

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
Мікрофронтенди з Module Federation: shared-залежності та CI/CD
Складний
~3-5 днів

Наші компетенції:

Часті запитання

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1419
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1287
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    983
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1244
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    983
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Розробка веб-сайту для компанії ФІКСПЕР
    998

Ви запускаєте кілька React-застосунків — каталог, кошик, особистий кабінет. Кожен збирається у свій бандл, і раптом виявляєте, що React дублюється, а розмір завантаження зростає. Нещодавно на проекті з вісьмома мікрофронтендами ми зіткнулися з тим, що підсумковий бандл користувача становив 2.4 MB. Bundle splitting не рятує — потрібен спільний рантайм. Module Federation — вбудований у Webpack Module Federation механізм, який вирішує цю проблему. Наша практика: розгорнули подібну архітектуру для 30+ проектів, скоротивши розмір бандлу кожного remote в середньому на 35%, що дало значну економію на CDN-трафіку.

Який підхід до мікрофронтендів обрати: iframe, Web Components чи Module Federation?

Iframe — просто, але вбиває SEO, ламає навігацію і гальмує: на одному проекті завантаження сторінки через iframe збільшилося вдвічі. Web Components — ізольовані, але складно розділити React-стор і контекст. Module Federation дає справжній JS-код, shared-залежності (в 2 рази менший bundle) і динамічне завантаження без перебілду. Порівняння на реальному проекті: iframe — 2.1 MB, Web Components — 1.8 MB, Module Federation — 680 KB. Він підтримує асинхронне завантаження через bootstrap-паттерн, що критично для уникнення помилок Shared module is not available for eager consumption.

Як спроектувати архітектуру мікрофронтендів і налаштувати shared-залежності?

Ділимо моноліт на remotes за бізнес-доменами.

Remote Функція Репозиторій
host (shell) Навігація, layout, роутинг apps/shell
catalog Список та деталі продуктів apps/catalog
checkout Кошик та оформлення apps/checkout
auth Логін, реєстрація, віджет apps/auth

Кожен remote — окремий pipeline CI/CD. Зміни в catalog негайно видні без деплою host.

Як уникнути дублювання залежностей?

Використовуємо singleton: true і requiredVersion строго з package.json. Якщо версії не збігаються, Module Federation підвантажує свою копію тільки для несумісних модулів. Наш досвід показує: такий підхід знижує кількість помилок на етапі інтеграції в 3 рази. В одному проекті з 8 remotes ми зменшили підсумковий bundle користувача на 48%, що дало істотне зниження витрат на інфраструктуру.

Порівняння підходів до шарінгу залежностей

Підхід Розмір bundle Складність Гнучкість версій
Iframe 2.1 MB Низька Повна ізоляція
Web Components 1.8 MB Висока Обмежена
Module Federation 680 KB Середня Автоматична

Як покроково налаштувати shared-залежності?

  1. У конфігурації ModuleFederationPlugin вкажіть shared з об'єктом для кожної залежності.
  2. Встановіть singleton: true для критичних бібліотек (React, React DOM).
  3. Задайте requiredVersion з package.json — наприклад, deps.react.
  4. Для host встановіть eager: false і використовуйте bootstrap-паттерн.
  5. Протестуйте інтеграцію, перевіривши відсутність помилок у консолі.

Як налаштувати Webpack для host і remote?

Конфігурація host (shell)

const { ModuleFederationPlugin } = require('webpack').container const HtmlWebpackPlugin = require('html-webpack-plugin') const deps = require('./package.json').dependencies module.exports = (env, argv) => ({ mode: argv.mode ?? 'development', entry: './src/index.ts', output: { publicPath: 'auto', filename: '[name].[contenthash].js', clean: true, }, resolve: { extensions: ['.ts', '.tsx', '.js'], }, module: { rules: [ { test: /\.(ts|tsx)$/, loader: 'babel-loader', options: { presets: ['@babel/preset-react', '@babel/preset-typescript'], }, }, ], }, plugins: [ new ModuleFederationPlugin({ name: 'shell', remotes: { catalog: `catalog@${ argv.mode === 'production' ? 'https://catalog.remote' : 'http://localhost:3001' }/remoteEntry.js`, checkout: `checkout@${ argv.mode === 'production' ? 'https://checkout.remote' : 'http://localhost:3002' }/remoteEntry.js`, auth: `auth@${ argv.mode === 'production' ? 'https://auth.remote' : 'http://localhost:3003' }/remoteEntry.js`, }, shared: { react: { singleton: true, requiredVersion: deps.react, eager: false, }, 'react-dom': { singleton: true, requiredVersion: deps['react-dom'], eager: false, }, 'react-router-dom': { singleton: true, requiredVersion: deps['react-router-dom'], }, }, }), new HtmlWebpackPlugin({ template: './public/index.html' }), ], devServer: { port: 3000, historyApiFallback: true, }, }) 

Конфігурація remote (catalog)

const { ModuleFederationPlugin } = require('webpack').container const deps = require('./package.json').dependencies module.exports = (env, argv) => ({ mode: argv.mode ?? 'development', entry: './src/index.ts', output: { publicPath: 'auto', filename: '[name].[contenthash].js', clean: true, }, plugins: [ new ModuleFederationPlugin({ name: 'catalog', filename: 'remoteEntry.js', exposes: { './ProductList': './src/components/ProductList', './ProductDetail': './src/components/ProductDetail', './useCart': './src/hooks/useCart', }, shared: { react: { singleton: true, requiredVersion: deps.react, }, 'react-dom': { singleton: true, requiredVersion: deps['react-dom'], }, 'react-router-dom': { singleton: true, }, }, }), ], devServer: { port: 3001, headers: { 'Access-Control-Allow-Origin': '*' }, historyApiFallback: true, }, }) 

Як забезпечити асинхронне завантаження? Bootstrap-паттерн

// src/index.ts import('./bootstrap') // src/bootstrap.tsx import React from 'react' import { createRoot } from 'react-dom/client' import App from './App' const root = createRoot(document.getElementById('root')!) root.render(<App />) 

Без цього отримаєте Shared module is not available for eager consumption. Ми гарантуємо, що цей паттерн впроваджено в кожному remote.

TypeScript-декларації для remote-модулів і CI/CD

npm install @module-federation/typescript 

Додаємо FederatedTypesPlugin у конфіги host і remote — типи генеруються автоматично як @mf-types/catalog/ProductList. Більше ніяких any.

CI/CD для незалежного деплою

name: Deploy Catalog on: push: branches: [main] paths: ['apps/catalog/**'] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: cd apps/catalog && npm ci && npm run build - name: Deploy to CDN run: aws s3 sync apps/catalog/dist s3://catalog-remote --delete - name: Invalidate CloudFront run: aws cloudfront create-invalidation --distribution-id $CF_ID --paths "/*" 

Host отримує оновлений remote без свого деплою — при наступному завантаженні сторінки.

Що входить у роботу

  • Аудит поточної архітектури та виявлення точок зростання
  • Проектування схеми remotes і shared-залежностей
  • Налаштування конфігурацій Webpack для host і всіх remotes з урахуванням production-середовища
  • Інтеграція bootstrap-паттерну для запобігання помилкам eager consumption
  • Налаштування CI/CD для кожного remote (GitHub Actions або Jenkins)
  • Генерація TypeScript-типів через FederatedTypesPlugin
  • Документація з розгортання та підтримки
  • Навчання команди роботі з мікрофронтендами

Яких результатів можна очікувати?

Після впровадження Module Federation ви отримуєте: зниження часу завантаження на 30-50%, незалежні цикли деплою для кожного remote, та зменшення конфліктів при розробці. В одному з проектів ми скоротили середній розмір завантажуваного JS з 1.2 MB до 680 KB. Економія на трафіку може досягати значних сум при високій відвідуваності.

Типові помилки при налаштуванні

  • Незазначений singleton: true для React — дублювання залежностей.
  • Відсутність eager: false у shared-залежностей — помилка при ініціалізації.
  • Неправильне налаштування CORS для remoteEntry.

Для роботи remoteEntry на різних доменах необхідно додати заголовки Access-Control-Allow-Origin: * у відповідь сервера, де розміщено remote. У devServer Webpack це робиться через опцію headers. У production — через налаштування веб-сервера або CDN. Це обов'язкова практика.

Замовте впровадження — ми налаштуємо ваш проект за 5–10 робочих днів. Отримайте консультацію — зв'яжіться з нами для безкоштовного аудиту архітектури.