В Webpack Module Federation загрузка remote модулей опирается на
асинхронное получение remoteEntry.js, его выполнение в
рантайме и последующее разрешение экспозированных модулей через
контейнер федерации. Ошибки могут возникать на каждом из этих этапов: от
сетевого запроса до выполнения фабрики модуля.
Классическая цепочка загрузки выглядит следующим образом:
remoteEntry.js<script> или
import()init)get(module)Любой сбой на этом пути требует различного подхода к обработке.
Наиболее частая категория проблем связана с невозможностью загрузить
remoteEntry.js.
Причины:
Типичный симптом в консоли:
Loading script failedFailed to fetch dynamically imported moduleScript errorДинамически загруженные скрипты через <script> не
всегда возвращают детализированную ошибку. В большинстве случаев
доступна только общая информация о падении загрузки, без
HTTP-статуса.
Webpack Module Federation позволяет перехватывать ошибку загрузки через кастомную обёртку динамического импорта.
Пример базового механизма:
function loadRemote(url) {
return new Promise((resolve, reject) => {
const script = document.createElement("script");
script.src = url;
script.type = "text/javascript";
script.async = true;
script.onl oad = () => resolve(true);
script.oner ror = () => {
reject(new Error(`Remote loading failed: ${url}`));
};
document.head.appendChild(script);
});
}
В реальных конфигурациях Module Federation аналогичная логика встроена в runtime, но может быть расширена через кастомные загрузчики.
После загрузки remoteEntry.js происходит инициализация
контейнера:
Ошибки на этом этапе часто связаны с:
Типичные сообщения:
Container initialization failedShared module is not availableUncaught Error: Shared module version mismatchПри использовании singleton: true Webpack требует
строгого соблюдения версии зависимости. Несовпадение может привести к
отказу инициализации контейнера.
Пример проблемной конфигурации:
shared: {
react: { singleton: true, requiredVersion: "^18.0.0" }
}
Если host использует React 18.2, а remote — 17.x, поведение зависит от стратегии разрешения версий и может привести к runtime-ошибке.
После успешной инициализации контейнера происходит вызов:
container.get("./module")
На этом этапе возможны следующие проблемы:
Причина:
exposes в remoteОшибка:
Module not foundCannot read properties of undefinedModule Federation ожидает корректный ESM-like интерфейс. Ошибки возникают при:
После получения модуля выполняется его фабрика. Это уже обычный runtime JavaScript-код, и ошибки здесь похожи на стандартные application errors.
Причины:
Пример:
export default function Module() {
return React.createElement("div", null, window.nonExisting.value);
}
Такие ошибки не отличаются от обычных runtime exceptions, но сложнее диагностируются из-за асинхронной природы загрузки.
Webpack предоставляет runtime hooks, позволяющие вмешиваться в процесс загрузки remote.
Можно перехватывать глобальные ошибки:
window.addEventListener("error", (e) => {
console.log("Global error:", e.message);
});
Однако этого недостаточно для федерации модулей.
Расширенный подход — обёртка вокруг init:
async function safeInit(container, shareScope) {
try {
await container.init(shareScope);
} catch (e) {
console.error("Init failed", e);
return null;
}
}
Это позволяет изолировать падение remote и предотвратить крах host-приложения.
Проблемы сети требуют повторных попыток загрузки
remoteEntry.js.
Базовая стратегия retry:
async function loadWithRetry(url, retries = 3) {
for (let i = 0; i < retries; i++) {
try {
await loadRemote(url);
return;
} catch (e) {
if (i === retries - 1) throw e;
}
}
}
При промышленной эксплуатации добавляются:
Архитектура Module Federation позволяет задавать альтернативные источники remote.
Пример стратегии:
Логика выбора:
Stub может выглядеть как:
export const fallbackModule = {
render: () => "Service unavailable"
};
Отдельная категория ошибок связана с кэшированием
remoteEntry.js.
Сценарии:
remoteEntry.[hash].jsДля анализа загрузки remote используются следующие подходы:
Проверка:
remoteEntry.jsВ dev-режиме:
Добавление логов:
const originalGet = container.get;
container.get = async (module) => {
console.log("Loading module:", module);
return originalGet(module);
};
Ключевой принцип устойчивой федерации — недопущение падения host-приложения из-за remote.
Подходы:
Пример React-изоляции:
class RemoteBoundary extends React.Component {
state = { error: null };
static getDerivedStateFromError(error) {
return { error };
}
render() {
if (this.state.error) {
return "Remote module failed";
}
return this.props.children;
}
}
При возникновении ошибки загрузки remote последовательность анализа обычно сводится к следующему:
remoteEntry.jsexposesModule Federation допускает частичную работоспособность системы:
Это требует разделения ошибок:
Стабильность обеспечивается сочетанием:
Основной принцип: remote не должен становиться единой точкой отказа для host-приложения.