基于Rollup的React宿主应用如何加载Webpack5联邦模块
Rollup宿主加载Webpack模块联邦远程模块实现方案
Rollup没有内置模块联邦能力,直接对接Webpack暴露的联邦模块需要用适配插件,具体实现步骤如下:
1. 安装宿主侧依赖
在宿主项目根目录执行安装命令,添加Rollup生态的模块联邦适配插件:
npm install @module-federation/rollup-federation -D
核心前提:宿主项目内的react、react-dom版本必须和远程应用package.json中声明的版本范围匹配,满足远程shared配置里的requiredVersion约束,否则单例模式会失效,触发React多实例的钩子报错。
2. 调整Rollup构建配置
打开宿主项目的rollup.config.js,引入模块联邦插件,添加远程映射、共享依赖配置,原有业务相关的Rollup插件(比如node解析、commonjs转换、babel转译、React编译插件)按原有顺序保留即可:
import federation from '@module-federation/rollup-federation' // 其他原有插件引入正常保留,例如: // import resolve from '@rollup/plugin-node-resolve' // import commonjs from '@rollup/plugin-commonjs' // import react from '@rollup/plugin-react' export default { // 原有input配置保持不变 input: 'src/index.jsx', output: { dir: 'dist', // 输出格式必须设为esm,不要用iife、cjs格式,否则模块联邦的动态加载逻辑无法正常运行 format: 'esm', // 其他output配置(比如sourcemap、asset路径规则)按项目原有需求保留 }, plugins: [ // 原有通用插件放在federation插件之前 // resolve(), // commonjs(), federation({ name: 'host_app', // 宿主自身的联邦模块标识,自定义即可,不能和远程应用的name重名 remotes: { // 远程映射规则:[远程Webpack配置里的name值]: "[远程name]@[远程服务地址]/remoteEntry.js" ResetPassword: 'ResetPassword@http://localhost:3000/remoteEntry.js' }, shared: { // 和远程配置对齐,将react、react-dom设为单例共享,避免多实例问题 react: { singleton: true, requiredVersion: require('./package.json').dependencies.react }, 'react-dom': { singleton: true, requiredVersion: require('./package.json').dependencies['react-dom'] } // 其余远程shared中声明的公共依赖,如果宿主也有使用,可以按相同规则添加到这里,减少重复加载 } }), // React编译类插件放在federation插件之后即可 // react() ] }
3. 业务代码中使用远程组件
模块联邦加载远程资源是异步逻辑,直接用React自带的lazy+Suspense处理加载态即可,导入路径和Webpack宿主的写法完全一致:
import React, { Suspense, lazy } from 'react' // 导入格式:[remotes中配置的远程映射名]/[远程exposes中暴露的路径] const RemoteResetPassword = lazy(() => import('ResetPassword/ResetPassword')) export default function App() { return ( <div className="app"> <h1>宿主应用页面</h1> <Suspense fallback={<div>组件加载中...</div>}> <RemoteResetPassword /> </Suspense> </div> ) }
关键注意事项
- 远程应用侧要开启跨域:如果是Webpack devServer启动的本地服务,需要在devServer配置中添加响应头
headers: { 'Access-Control-Allow-Origin': '*' },否则宿主加载remoteEntry.js时会被浏览器CORS策略拦截。 - 生产部署时,要把remotes配置里的远程地址替换成生产环境对应的实际服务地址,不要保留localhost本地地址。
- 不要在宿主构建配置中把react、react-dom打包成多份实例,必须严格遵守singleton单例规则,否则会触发React的invalid hook call报错。
- 如果远程暴露的模块有其他公共依赖(比如antd、lodash),可以按需加到shared配置里,和远程共享实例,减少包体积。
内容的提问来源于stack exchange,提问作者Neon
相关产品推荐
相关产品推荐

