Что такое Module Federation в Webpack и зачем он нужен?

SeniorJavaScript · Frontend·Обновлено 15 августа 2026
Коротко
Module Federation — механизм Webpack 5, позволяющий независимо собранным и задеплоенным приложениям динамически подключать код друг друга в рантайме через асинхронную загрузку удалённых модулей. Это основной инструмент для построения микрофронтендов без дублирования зависимостей и без пересборки всего приложения при изменении одной его части.

Идея и назначение

Module Federation (MF) — фича Webpack 5, которая позволяет нескольким независимо собранным JS-приложениям подключать модули друг из друга во время выполнения, а не на этапе сборки. Это база для микрофронтендов: разные команды пишут, собирают и деплоят свои приложения отдельно, а в браузере они объединяются в единое целое.

Host и Remote

  • Remote — приложение, которое отдаёт свои модули наружу через exposes.
  • Host — приложение, которое подключает чужие модули через remotes.
  • Одно и то же приложение может одновременно быть и host, и remote (bidirectional federation), что типично для сеток микрофронтендов.

Конфигурация

Всё настраивается через ModuleFederationPlugin: name — имя контейнера, filename — обычно remoteEntry.js, exposes — какие модули отдаём, remotes — откуда берём чужие модули, shared — общие зависимости (react, react-dom и т.д.), чтобы не тащить их дублями в разные бандлы.

Как это работает под капотом

При сборке remote генерирует специальный файл-контейнер (remoteEntry.js) — runtime-обёртку с реестром модулей и их асинхронными загрузчиками. Host в рантайме подгружает этот скрипт динамическим <script>-тегом, получает глобальный объект-контейнер, согласовывает shared-скоуп (сравнение версий общих зависимостей по semver) и запрашивает нужный модуль через container.get('./Module'). Импорт всегда асинхронный, поэтому используется динамический import(), обычно обёрнутый в React.lazy + Suspense.

Shared-зависимости

Поле shared решает проблему дублирования библиотек. Если host и remote оба используют react, объявляем её как shared с singleton: true, чтобы в рантайме работал один инстанс — это критично для контекста, хуков и синглтон-состояния. Webpack сверяет версии и решает, чей билд библиотеки грузить, либо выдаёт предупреждение при несовместимости.

Отличия от прежних подходов к интеграции

До MF независимые фронтенды соединяли через iframe (изоляция, но проблемы со стилями/роутингом/производительностью), общие npm-пакеты с компонентами (требуют пересборки и передеплоя при любом изменении) или Single-SPA с ручной загрузкой скриптов. Module Federation даёт нативный для бандлера механизм с поддержкой code splitting, версионирования зависимостей и полностью независимого деплоя частей приложения.

Применение шире микрофронтендов

MF используют и для плагинных архитектур (динамическая загрузка плагинов без пересборки хоста), A/B-тестирования отдельных фич, постепенной миграции legacy-кода на новый стек.

Ограничения и подводные камни

Изначально доступен только в Webpack 5 (позже появились независимые реализации вроде @module-federation/enhanced, портированные на Vite и Rspack). Рассинхрон версий shared-зависимостей — частый источник рантайм-ошибок, которые сборка не ловит. Для TypeScript типы remote-модулей по умолчанию недоступны статически — их генерируют отдельно, например через dts-плагины экосистемы Module Federation.

Что хочет услышать интервьюер

Кандидат объясняет разницу между host и remote и то, что импорт remote-модулей всегда асинхронный

Упоминает поле shared и singleton для избежания дублирования и рассинхрона версий react/react-dom

Понимает, что модули подключаются в рантайме через remoteEntry.js, а не на этапе сборки

Может связать Module Federation с архитектурой микрофронтендов и независимым деплоем

Знает про ограничения: версии зависимостей, отсутствие типов из коробки, привязку к Webpack 5

Пример: webpack.config.js remote-приложения

const { ModuleFederationPlugin } = require('webpack').container;

module.exports = {
  // ...
  plugins: [
    new ModuleFederationPlugin({
      name: 'shop',
      filename: 'remoteEntry.js',
      exposes: {
        // отдаём компонент наружу под именем './ProductList'
        './ProductList': './src/components/ProductList',
      },
      shared: {
        react: { singleton: true, requiredVersion: '^18.0.0' },
        'react-dom': { singleton: true, requiredVersion: '^18.0.0' },
      },
    }),
  ],
};

Пример: webpack.config.js host-приложения

const { ModuleFederationPlugin } = require('webpack').container;

module.exports = {
  // ...
  plugins: [
    new ModuleFederationPlugin({
      name: 'app',
      remotes: {
        // shop — локальное имя, адрес remoteEntry.js отдельного деплоя
        shop: 'shop@https://shop.example.com/remoteEntry.js',
      },
      shared: {
        react: { singleton: true, requiredVersion: '^18.0.0' },
        'react-dom': { singleton: true, requiredVersion: '^18.0.0' },
      },
    }),
  ],
};

Пример: Использование remote-модуля в host

import { lazy, Suspense } from 'react';

// импорт всегда асинхронный — модуль подгружается по сети в рантайме
const ProductList = lazy(() => import('shop/ProductList'));

function App() {
  return (
    <Suspense fallback={<div>Загрузка...</div>}>
      <ProductList />
    </Suspense>
  );
}

Типичные ошибки

Путают Module Federation с обычным code splitting или dynamic import внутри одного приложения

Забывают указать shared-зависимости или singleton, из-за чего в рантайме грузится несколько копий react

Считают, что импорт remote-модуля синхронный и не оборачивают его в Suspense/lazy

Не могут объяснить, что такое remoteEntry.js и как host находит и инициализирует container

Игнорируют проблему версионирования и деплоя remotes — не учитывают, что remote может обновиться независимо и сломать host

Лучшие курсы по теме

изображение курса

TypeScript с нуля

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Feature-Sliced Design

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.6
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Next.js - с нуля

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее