You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Module Federation在同域主应用与IFrame间共享React依赖?

同域主应用与IFrame共享React等依赖的实现方案

一、原生全局挂载方案(无需Module Federation)

直接通过window全局对象共享库实例,简单易落地:

  1. 主应用侧操作:在主应用入口文件中,将需要共享的库挂载到全局window:
import React from 'react';
import ReactDOM from 'react-dom/client';

// 挂载全局共享对象,命名需唯一避免冲突
window.SharedReact = React;
window.SharedReactDOM = ReactDOM;
  1. IFrame侧配置:在IFrame的Webpack配置中,用externals声明依赖从全局获取,避免重复打包:
// IFrame的webpack.config.js
module.exports = {
  // 其他配置...
  externals: {
    react: 'SharedReact',
    'react-dom': 'SharedReactDOM'
  }
};

此时IFrame打包时不会将React/ReactDOM打入bundle,运行时直接引用主应用挂载的全局实例,实现依赖共享。

二、适配Module Federation的跨IFrame共享方案

你提到的Module Federation作者所说的“全局对象”,指的是主应用暴露到全局的Webpack模块容器。通过让IFrame访问该容器,即可实现跨上下文的依赖共享:

  1. 主应用侧配置:
    常规配置Module Federation共享规则,同时将模块容器挂载到全局:
// 主应用webpack.config.js
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');

module.exports = {
  // 其他配置...
  plugins: [
    new ModuleFederationPlugin({
      name: 'hostApp',
      shared: {
        react: { singleton: true, eager: true },
        'react-dom': { singleton: true, eager: true }
      }
    })
  ]
};

// 主应用入口文件(bootstrap前)
window.hostContainer = __webpack_container__; // 暴露主应用模块容器到全局
import('./bootstrap');
  1. IFrame侧配置:
    配置Module Federation时禁止本地加载共享依赖,然后从主应用的全局容器获取实例:
// IFrame的webpack.config.js
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');

module.exports = {
  // 其他配置...
  plugins: [
    new ModuleFederationPlugin({
      name: 'iframeApp',
      shared: {
        react: { 
          singleton: true, 
          eager: true,
          import: false, // 禁止从IFrame本地加载
          requiredVersion: '^18.0.0' // 需与主应用版本一致
        },
        'react-dom': { 
          singleton: true, 
          eager: true,
          import: false,
          requiredVersion: '^18.0.0'
        }
      }
    })
  ]
};

// IFrame入口文件
import { initSharing } from '@module-federation/runtime';

async function initSharedDependencies() {
  // 初始化共享范围
  await initSharing('default');
  // 从主应用全局容器获取共享模块
  const reactModule = await window.parent.hostContainer.get('./react');
  const reactDomModule = await window.parent.hostContainer.get('./react-dom');
  
  // 将获取到的模块挂载到IFrame全局,供内部使用
  window.SharedReact = reactModule.default;
  window.SharedReactDOM = reactDomModule.default;
  
  // 加载IFrame业务代码
  import('./bootstrap');
}

// 确保主应用容器已挂载后再初始化
if (window.parent.hostContainer) {
  initSharedDependencies();
} else {
  // 监听主应用容器挂载事件(可选)
  window.parent.addEventListener('containerReady', initSharedDependencies);
}

关键注意事项

  • 主应用与IFrame的依赖版本必须完全匹配,否则会引发实例不兼容问题;
  • 全局变量命名需唯一,避免与其他脚本冲突;
  • 使用Module Federation时,eager: true确保共享模块在入口阶段加载,保证IFrame能获取到实例;
  • 若使用React 18+,需注意ReactDOM.createRoot的调用方式与全局实例的兼容性。

内容的提问来源于stack exchange,提问作者Diogo Soares

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 14:25:12