Микрофронтенды
Разделение большого фронтенда по командам: Module Federation, паттерны композиции и реальная цена.
За 30 секунд
Микрофронтенды делят одно большое веб-приложение на меньшие фронтенд-части, которые разные команды независимо разрабатывают, тестируют и деплоят, а затем объединяют в единый опыт для пользователя. Это фронтенд-версия микросервисов. Сделанные по правильным причинам, они позволяют многим командам двигаться, не блокируя друг друга; сделанные слишком рано, добавляют много сложности, дублирующегося кода и замедляют страницы.
Не в моём ежедневном стеке — я понимаю принципы и изучу детали, когда это понадобится проекту.
Почему это важно
- В крупных организациях один фронтенд, которым владеют многие команды, становится узким местом: один release train, один пайплайн, бесконечные merge-конфликты.
- Микрофронтенды позволяют каждой команде владеть бизнес-областью целиком, от базы данных до UI, и деплоить по своему графику.
- Они делают возможной постепенную миграцию, например перенос старого приложения на AngularJS или jQuery на React страница за страницей вместо рискованного переписывания с нуля.
- Понимание паттерна помогает и распознать, когда он не нужен, — а это более частое и ценное решение.
Как это работает
01Идея: делить по командам и бизнес-доменам
Представьте e-commerce сайт, который делают шесть команд: поиск, страницы товаров, checkout, аккаунт, контент и маркетинг. В единой фронтенд-кодовой базе каждое изменение проходит через одну сборку и один деплой, и баг в checkout может заблокировать релиз поиска. С микрофронтендами каждая команда владеет вертикальным срезом: своим репозиторием или пакетом, своим пайплайном и своим деплоем. Shell (его ещё называют host или container app) даёт каркас страницы, роутинг и общие сервисы и загружает нужный микрофронтенд для каждой области. Представьте торговый центр: одно здание, общие коридоры и охрана, но каждый магазин работает независимо. Ключевой принцип — делить по бизнес-возможностям, а не по техническим слоям вроде «команды хедера» и «команды кнопок».
- Shell / host: собирает страницу и владеет роутингом и глобальными задачами.
- Remote / микрофронтенд: независимо деплоящаяся часть UI.
- Контракт: согласованный интерфейс между shell и remote (props, события, роуты).
02Способы композиции микрофронтендов
Композиция может происходить в разное время и в разных местах. Интеграция на этапе сборки публикует каждую часть как npm-пакет, который импортирует shell; это просто и быстро, но теряется независимый деплой, потому что shell нужно пересобирать. Серверная композиция сшивает HTML-фрагменты на сервере или edge (Edge Side Includes, сервис композиции или возможности фреймворков вроде Next.js Multi-Zones, где разные приложения владеют разными путями URL за одним доменом). Интеграция в рантайме загружает JavaScript от каждой команды в браузере: Module Federation, import maps с нативными ES-модулями или Web Components. Iframe дают самую сильную изоляцию, но плохую интеграцию с layout, роутингом и доступностью. Самый простой эффективный подход часто — разделение на уровне роутов: каждая команда владеет целыми страницами, а общей остаётся только навигация shell.
03Module Federation простыми словами
Module Federation, появившийся в webpack 5 и теперь доступный как самостоятельный рантайм (Module Federation 2.0) с плагинами для webpack, Rspack, Rsbuild и Vite, позволяет одной сборке загружать модули из другой сборки во время выполнения. Remote открывает модули (например, ./ProductPage) через небольшой entry-файл, который часто называется remoteEntry.js или описывается mf-manifest.json. Host объявляет remote и импортирует их модули так, будто они локальные; код загружается только при необходимости. Общие зависимости вроде React объявляются как синглтоны, чтобы страница загружала одну копию, а диапазоны версий согласуются в рантайме. Версия 2.0 добавляет протокол манифестов, подсказки типов для remote, систему runtime-плагинов и devtools.
// rsbuild.config.ts (remote: product team)
import { defineConfig } from "@rsbuild/core";
import { pluginReact } from "@rsbuild/plugin-react";
import { pluginModuleFederation } from "@module-federation/rsbuild-plugin";
export default defineConfig({
plugins: [
pluginReact(),
pluginModuleFederation({
name: "product",
exposes: { "./ProductPage": "./src/ProductPage.tsx" },
shared: {
react: { singleton: true, requiredVersion: "^19.0.0" },
"react-dom": { singleton: true, requiredVersion: "^19.0.0" },
},
}),
],
server: { port: 3001 },
});
04Подключение remote в shell
Host объявляет, где живёт каждый remote, и лениво загружает его модули. Оборачивайте каждый remote в error boundary и fallback на время загрузки: remote — это сетевая зависимость, которая может упасть или тормозить, и одна сломанная команда не должна ломать всю страницу. В продакшене URL remote должны браться из конфигурации или сервиса манифестов, а не быть зашиты в код, чтобы команды могли деплоить и откатываться без пересборки shell.
// host: rsbuild.config.ts (excerpt)
pluginModuleFederation({
name: "shell",
remotes: { product: "product@https://cdn.example.com/product/mf-manifest.json" },
shared: { react: { singleton: true }, "react-dom": { singleton: true } },
});
// host: src/routes/ProductRoute.tsx
import { lazy, Suspense } from "react";
import { ErrorBoundary } from "react-error-boundary";
const ProductPage = lazy(() => import("product/ProductPage"));
export function ProductRoute() {
return (
<ErrorBoundary fallback={<p>Product details are unavailable right now.</p>}>
<Suspense fallback={<p>Loading…</p>}>
<ProductPage />
</Suspense>
</ErrorBoundary>
);
}
05Взаимодействие и общее состояние
Микрофронтенды должны быть слабо связаны, поэтому они общаются через небольшие явные контракты, а не через общий глобальный стор. Распространённые варианты: URL и роутинг как основное состояние (ID товара живёт в URL), props, которые shell передаёт при монтировании remote, кастомные события браузера для уведомлений вроде «корзина обновлена» и бэкенд-API как источник истины, который каждая часть читает самостоятельно. Избегайте одного глобального Redux-стора, общего для всех команд: он воссоздаёт ту самую связанность, от которой вы уходили, разделяя приложение. Аутентификацией обычно владеет shell, который предоставляет функцию получения токена или контекст пользователя через крошечный общий интерфейс.
// Contract: a typed custom event
type CartUpdated = { count: number };
// Checkout micro-frontend
window.dispatchEvent(new CustomEvent<CartUpdated>("cart:updated", { detail: { count: 3 } }));
// Shell header
window.addEventListener("cart:updated", (e) => {
const { count } = (e as CustomEvent<CartUpdated>).detail;
renderBadge(count);
});
06Дизайн-системы и единообразие
Самый заметный для пользователя риск — непоследовательный продукт: разные кнопки, отступы и поведение от каждой команды. Это решает общая дизайн-система: дизайн-токены (цвета, отступы, типографика как CSS-переменные), библиотека компонентов, опубликованная как версионированный пакет, и документация в Storybook. Команды используют её как любую другую зависимость. Важна и изоляция стилей: используйте CSS Modules, префикс для каждого микрофронтенда или Shadow DOM для Web Components, чтобы глобальный CSS одной команды не ломал страницу другой. Ломающие изменения в дизайн-системе должны быть редкими и анонсированными, потому что обновляться придётся каждой команде; токены в виде CSS-переменных позволяют менять темы в рантайме без передеплоя каждого remote.
07Монорепозиторий или полирепозиторий — и само решение
Микрофронтенды — про независимый деплой, а не обязательно про отдельные репозитории. Многие команды используют монорепозиторий (Nx, Turborepo, pnpm workspaces) с папкой на каждый микрофронтенд, отдельными пайплайнами сборки и деплоя, которые запускаются затронутыми изменениями, и общими инструментами. Так рефакторинг и обновление зависимостей остаются простыми, а владение командами сохраняется. Полирепозитории максимизируют автономию, но усложняют общие обновления и единообразие. Прежде чем выбирать, спросите, нужны ли вам микрофронтенды вообще: при менее чем трёх-четырёх фронтенд-командах хорошо структурированный модульный монолит с понятным владением папками, границами под контролем линтера и быстрым CI обычно даёт те же преимущества без сложности рантайма.
Когда применять
- Несколько автономных команд (часто четыре и больше), работающих над одним продуктом и блокирующих друг друга релизами.
- Постепенная миграция с устаревшего фронтенд-фреймворка на новый, область за областью.
- Продукты, собранные из областей с разными владельцами, например портал, объединяющий инструменты разных отделов.
- Когда независимый деплой и изоляция сбоев стоят дополнительной инфраструктуры и governance.
Когда не стоит
- Небольшие команды или одна команда; накладные расходы перевешивают любую пользу, а модульный монолит проще.
- Критичные к производительности потребительские страницы, где лишний JavaScript, дублирующиеся зависимости и водопады загрузки бьют по конверсии.
- Когда настоящая проблема — медленный CI или запутанный код, которые дешевле исправить лучшей структурой и инструментами.
Альтернативы
- Модульный монолит на фронтенде
Одно приложение и один деплой со строгими внутренними границами модулей и владением; проще всего для большинства команд.
- Монорепозиторий с Nx / Turborepo
Общие инструменты и сборка только затронутого; может оставаться одним приложением или позже вырасти в микрофронтенды.
- Next.js Multi-Zones
Несколько Next.js-приложений обслуживают разные пути URL под одним доменом; разделение по роутам без federation в рантайме.
- Серверная композиция / острова
Сборка HTML на сервере или edge; хорошо подходит для контентных страниц.
Лучшие практики
- Делите по бизнес-доменам и владению командами, а не по техническим слоям.
- Предпочитайте владение на уровне роутов; смешение компонентов многих команд на одном экране умножает координацию.
- Делитесь как можно меньшим: синглтонами фреймворка и дизайн-системой, а не бизнес-логикой или глобальными сторами.
- Оборачивайте каждый remote в error boundary и fallback и отслеживайте ошибки по каждому микрофронтенду.
- Храните URL remote в runtime-конфигурации, чтобы команды могли деплоить и откатываться независимо.
- Версионируйте контракты между shell и remote и проверяйте их контрактными или интеграционными тестами в CI.
- Задайте бюджет производительности для собранной страницы и измеряйте реальный пользовательский опыт, а не каждую часть по отдельности.
Частые ошибки
- Внедрение микрофронтендов в небольшой команде, потому что это звучит масштабируемо, а затем утопание в конфигурации.
- Загрузка нескольких копий React или разных версий дизайн-системы на одной странице.
- Общий глобальный стор состояния, который снова связывает все команды вместе.
- Отсутствие fallback при падении remote, из-за чего сломанный деплой одной команды кладёт весь сайт.
- Выбор каждой командой своего фреймворка без веской причины для миграции, что умножает размер бандла и требования к найму.
Глубже
08Общие зависимости и согласование версий
Share scope в Module Federation — это реестр в рантайме, где каждая загруженная сборка регистрирует общие пакеты, которые она приносит, с их версиями. Когда модулю нужен React, рантайм выбирает версию, удовлетворяющую requiredVersion, предпочитая самую высокую из доступных, а singleton: true принудительно оставляет ровно один экземпляр, что требуется React, React DOM, роутерам и библиотекам на контексте, потому что две копии ломают хуки и контекст. Если совместимой версии нет, синглтон пишет предупреждение и всё равно использует загруженную, что может приводить к тонким багам; strictVersion превращает это в ошибку. eager: true включает общий модуль в начальный чанк, что убирает асинхронную границу, но увеличивает размер. Обычный паттерн — асинхронный bootstrap: entry-файл делает import('./bootstrap'), чтобы общие модули успели согласоваться до старта приложения.
// src/index.ts (entry)
import("./bootstrap");
// src/bootstrap.tsx
import { createRoot } from "react-dom/client";
import { App } from "./App";
createRoot(document.getElementById("root")!).render(<App />);
// shared config with strict checks for critical libs
// shared: {
// react: { singleton: true, requiredVersion: "^19.0.0", strictVersion: true },
// "@acme/design-system": { singleton: true, requiredVersion: "^4.2.0" },
// }
09Деплой, обнаружение и откаты
Для независимого деплоя shell нужен способ находить текущую версию каждого remote. Если зашить URL в сборку shell, деплои оказываются связанными. Лучше так: каждый remote публикует неизменяемые версионированные ресурсы (product/1.14.2/mf-manifest.json) в CDN, а небольшой discovery-документ или сервис сопоставляет имена remote с активной версией для каждого окружения. Shell читает его при старте, либо runtime-плагины Module Federation разрешают remote динамически. Откат означает перенаправить карту на предыдущую версию, ничего не пересобирая. Это также позволяет делать canary-релизы и переопределения для отдельных пользователей при тестировании. Кэшируйте discovery-документ ненадолго, а ресурсам давайте долгий срок кэширования, потому что их пути версионированы.
// remotes.json served by a config endpoint (short cache)
{
"product": "https://cdn.example.com/product/1.14.2/mf-manifest.json",
"checkout": "https://cdn.example.com/checkout/3.2.0/mf-manifest.json"
}
// shell bootstrap with the MF runtime
import { init } from "@module-federation/enhanced/runtime";
const remotes = await (await fetch("/config/remotes.json")).json();
init({
name: "shell",
remotes: Object.entries(remotes).map(([name, entry]) => ({ name, entry: entry as string })),
});
10Изоляция: CSS, глобальные объекты и сбои
Композиция в рантайме помещает код нескольких команд в один документ, поэтому изоляцию нужно проектировать. CSS: глобальные селекторы одного remote могут перестилизовать другой; используйте CSS Modules или scoped-стили фреймворка, добавляйте префикс ко всем глобальным классам и держите reset-стили только в shell. Web Components с Shadow DOM дают жёсткие границы стилей ценой более сложной темизации (используйте CSS custom properties, которые проходят сквозь shadow-границу). Глобальные объекты JavaScript: никогда не патчите window или прототипы в remote и добавляйте пространство имён к любым ключам хранилища. Сбои: error boundary на каждый remote, таймауты на загрузку remote и fallback UI сохраняют страницу рабочей. Помечайте ошибки и метрики производительности именем и версией remote, чтобы дежурные инженеры знали, какую команду поднимать.
11Серверная композиция и SSR
Federation на клиенте подходит для приложений за логином, но публичным страницам нужны быстрый first paint и SEO. Варианты: серверные приложения на уровне роутов за одним доменом (Next.js Multi-Zones или reverse proxy, направляющий /checkout в одно приложение, а /blog — в другое) — просто и надёжно, но между зонами происходит полная перезагрузка страницы; композиция HTML-фрагментов на edge или сервере, когда layout-сервис параллельно забирает фрагменты от каждой команды и стримит их; или federated SSR, когда Module Federation загружает remote-модули и на Node.js-сервере — мощно, но сложно в эксплуатации из-за серверного кэширования и памяти. Для большинства публичных сайтов прагматичный ответ — зоны на уровне роутов плюс общая дизайн-система и пакет хедера.
# nginx: route-level composition under one domain
location /checkout/ { proxy_pass http://127.0.0.1:3002; }
location /account/ { proxy_pass http://127.0.0.1:3003; }
location / { proxy_pass http://127.0.0.1:3001; } # main shop
Реальные ситуации
Миграция устаревшей админки на AngularJS на React
Проблема
Большая админ-панель на AngularJS больше не поддерживается. Полное переписывание займёт год и заморозит развитие функций. Бизнес хочет новые экраны на React уже сейчас.
Как решить
Используйте паттерн strangler с shell. Поставьте впереди тонкий shell, который владеет роутингом и layout. Для старых роутов монтируйте legacy-приложение, а новые и переписанные экраны делайте как React-микрофронтенды, зарегистрированные на свои роуты и загружаемые через Module Federation или single-spa. Аутентификацию делите через небольшой API shell. Мигрируйте экран за экраном, начиная с самых ценных или чаще всего меняющихся, и удаляйте legacy-роуты по мере их замены. Когда последний legacy-экран исчезнет, shell можно свернуть в обычное React-приложение, так что микрофронтенды не остаются навсегда, если они не нужны командам.
Деплой одной команды сломал весь сайт
Проблема
Remote выкатил бандл, который падает при загрузке. Поскольку shell импортирует его на верхнем уровне, каждая страница показывает белый экран.
Как решить
Немедленно откатитесь, перенаправив discovery-карту на предыдущую версию remote. Затем укрепите shell: лениво загружайте каждый remote только на его роутах, оборачивайте его в error boundary с полезным fallback и добавьте таймаут загрузки. Добавьте smoke-тест после деплоя, который загружает собранную страницу в headless-браузере до продвижения новой версии, и отслеживайте ошибки с пометкой по remote с алертами. С версионированными неизменяемыми ресурсами и обнаружением в рантайме откат становится изменением конфига, которое занимает секунды.
Небольшая команда задумалась о микрофронтендах
Проблема
Стартап с пятью фронтенд-разработчиками на одном продукте замечает, что его Next.js-приложение становится запутанным, а CI — медленным. Кто-то предлагает разделить его на микрофронтенды.
Как решить
Сначала устраните настоящую боль. Реорганизуйте приложение в модули фич с понятными публичными интерфейсами, закрепите границы правилами ESLint или Nx module boundaries и добавьте CODEOWNERS для каждой фичи. Ускорьте CI кэшированием и тестами только затронутого через Turborepo или Nx. Вынесите дизайн-систему во внутренний пакет. Возвращайтесь к микрофронтендам только тогда, когда несколько независимых команд действительно блокируют друг друга релизами. При пяти разработчиках композиция в рантайме добавит проблем с инфраструктурой, версионированием и производительностью, не решив проблему структуры кода.
Шпаргалка
- Открыть модуль (MF)
exposes: { "./ProductPage": "./src/ProductPage.tsx" }- Объявить remote (MF manifest)
remotes: { product: "product@https://cdn.example.com/product/mf-manifest.json" }- Один экземпляр React на всех
shared: { react: { singleton: true, requiredVersion: "^19.0.0" } }- Асинхронный bootstrap в entry
import("./bootstrap");- Ленивая загрузка remote (React)
const Page = lazy(() => import("product/ProductPage"))- Событие между приложениями
window.dispatchEvent(new CustomEvent("cart:updated", { detail }))- Плагин MF для Rsbuild
npm i -D @module-federation/rsbuild-plugin- Сборка только затронутого (Nx)
npx nx affected -t build test
Вопросы и ответы
Q1Какую проблему на самом деле решают микрофронтенды?
Они решают скорее организационную проблему, чем техническую. Когда много команд работают в одной фронтенд-кодовой базе, у них общий release train, пайплайн и дерево зависимостей, поэтому они блокируют друг друга, а владение размывается. Микрофронтенды позволяют каждой команде владеть бизнес-областью целиком и деплоить независимо, а сбои изолированы в её части. Они также делают возможной постепенную миграцию между фреймворками. Они не ускоряют одну команду, сами по себе не улучшают производительность и добавляют сложности с интеграцией в рантайме, версионированием и единообразием. Поэтому первый вопрос всегда такой: есть ли у нас проблема масштабирования команд?
Q2Что такое Module Federation?
Module Federation позволяет отдельно собранным и задеплоенным JavaScript-приложениям загружать код друг друга во время выполнения. Remote-приложение открывает модули через небольшой entry- или manifest-файл; host-приложение объявляет этот remote и лениво импортирует его модули, как будто это локальные пакеты. Общие зависимости вроде React объявляются как синглтоны, поэтому браузер загружает одну совместимую копию, а не по копии на каждую команду. Всё началось с webpack 5; Module Federation 2.0 — самостоятельный рантайм с плагинами для webpack, Rspack, Rsbuild и Vite, а также манифестами, подсказками типов и devtools.
Q3Как микрофронтенды общаются между собой?
Как можно меньше и как можно явнее. URL — лучшее общее состояние: если checkout нужен ID товара, он читает роут. Shell может передавать props или небольшой объект контекста при монтировании remote. Для уведомлений, например об изменении количества товаров в корзине, хорошо работают кастомные события браузера или крошечная типизированная шина событий. Каждый микрофронтенд загружает свои данные из бэкенд-API, которые и являются настоящим источником истины. Я избегаю общего глобального стора, потому что он заставляет команды согласовывать его структуру и версию, а это сводит смысл разделения на нет.
Q4Как сохранить единообразие UI между командами?
С помощью общей дизайн-системы, к которой относятся как к продукту: дизайн-токены для цвета, отступов и типографики, версионированная библиотека компонентов, документация в Storybook и встроенная доступность. Команды используют её как зависимость, в идеале как federated-синглтон или с узкими диапазонами версий, чтобы страница не загружала несколько версий. Изоляция стилей через CSS Modules, префиксы или Shadow DOM не даёт CSS одной команды протекать в область другой. Важен и governance: небольшая платформенная команда владеет дизайн-системой и shell, проверяет контракты и сохраняет пути обновления гладкими.
Q5Какие есть риски для производительности?
Несколько независимо собранных бандлов могут означать дублирующиеся библиотеки, лишние сетевые запросы и водопады загрузки: загружается shell, затем манифест remote, затем его чанки, затем его данные. Каждая команда может ещё и поставлять свои полифиллы и утилиты. Что помогает: делить зависимости фреймворка как синглтоны, предзагружать remote для вероятных следующих роутов, по возможности рендерить на сервере или пререндерить, задать бюджет производительности на уровне страницы и отслеживать Core Web Vitals собранной страницы. Лучше всего работает разделение по роутам, потому что пользователь загружает только remote для той страницы, на которой находится.
Q6Микрофронтенды или монорепозиторий?
Это разные оси. Монорепозиторий — про то, где живёт код; микрофронтенды — про то, как UI деплоится и собирается. Можно иметь одно приложение в монорепозитории, микрофронтенды в монорепозитории или микрофронтенды во многих репозиториях. Для большинства компаний монорепозиторий с Nx или Turborepo, чёткими границами пакетов и сборкой только затронутого снимает боль совместной работы без композиции в рантайме. Если позже командам понадобится полностью независимый деплой, тот же монорепозиторий может выпускать отдельно деплоящиеся микрофронтенды с общими инструментами и дизайн-системой — это гораздо проще, чем начинать с множества репозиториев.
Вопросы уровня senior
S1Как вы определяете границы между микрофронтендами?
Я начинаю со структуры команд и бизнес-возможностей, используя domain-driven design: bounded context вроде каталога, checkout и аккаунта часто хорошо ложатся на микрофронтенды и, в идеале, на бэкенд-сервисы, которыми владеет та же команда. У хорошей границы высокая связность внутри, мало стабильных взаимодействий снаружи и изменения, которые редко требуют совместного деплоя двух команд. Границы на уровне роутов предпочтительнее, потому что минимизируют общее пространство экрана. Признаки неудачного разделения — интенсивный обмен событиями между частями, частые согласованные релизы и общее состояние повсюду. Действует закон Конвея: если оргструктура не совпадает с разделением, архитектура со временем подстроится под оргструктуру, поэтому я выравниваю их осознанно.
S2Module Federation, import maps или Web Components: как выбирать?
Module Federation — самый мощный вариант для команд на одном фреймворке: общие зависимости с согласованием версий, ленивая загрузка и интеграция с бандлером, но он привязывает вас к поддерживаемым бандлерам и своему рантайму. Import maps с нативными ES-модулями основаны на стандартах и не зависят от бандлера, на них строятся single-spa и похожие загрузчики; чтобы делиться зависимостями, их нужно выносить на согласованные URL, что требует больше дисциплины. Web Components дают нейтральный к фреймворку инкапсулированный контракт — атрибуты внутрь, события наружу, — что идеально, когда команды используют разные фреймворки или потребитель — CMS, но каждый компонент может тянуть свой рантайм фреймворка, а SSR и интеграция с формами сложнее. Я часто их комбинирую: Module Federation для загрузки и обёртки на Web Components только на границах между фреймворками.
S3Какой governance нужен архитектуре микрофронтендов?
Автономия без governance превращается в хаос. Небольшая платформенная команда владеет shell, дизайн-системой, политикой общих зависимостей и инструментами деплоя. Команды договариваются о коротком списке правил: разрешённые фреймворки и мажорные версии, синглтон-зависимости, бюджеты производительности по роутам, стандарты доступности, конвенции для ошибок и аналитики и версионирование контрактов между shell и remote. Эти правила обеспечиваются инструментами, а не документами: CI проверяет размер бандла, общие версии и контрактные тесты; дашборды показывают Core Web Vitals и ошибки по каждому remote. Есть и процесс жизненного цикла для обновления общего фреймворка во всех командах, со сроками. Цель — чтобы команды были независимы в поставке, но единообразны в пользовательском опыте.
Глоссарий
- Микрофронтенд
- Независимо собираемая и деплоящаяся часть веб-интерфейса, которой владеет одна команда и которая встраивается в более крупное приложение.
- Shell (host)
- Приложение-контейнер, которое даёт layout, роутинг и общие сервисы и загружает микрофронтенды.
- Remote
- В Module Federation — сборка, которая открывает модули для загрузки другими приложениями во время выполнения.
- Module Federation
- Возможность бандлера и рантайма, позволяющая отдельно задеплоенным сборкам делиться модулями и загружать модули друг друга.
- Синглтон-зависимость
- Общая библиотека, которая принудительно загружается на странице только один раз, например React.
- Import map
- Возможность браузера сопоставлять «голые» имена модулей с URL, что позволяет композицию на нативных ES-модулях.
- Multi-Zones
- Паттерн Next.js, в котором отдельные приложения обслуживают разные пути URL под одним доменом.
- Паттерн strangler
- Постепенная замена устаревшей системы перенаправлением её частей на новый код, пока старая система не исчезнет.
Что изучить дальше
Есть идея продукта?Давайте создадим его.
Расскажите о своей идее, продукте или команде. Обычно отвечаю в течение одного рабочего дня.