Module Federation在webpack中动态配置远程资源运行报错如何解决
错误原因
- 远程应用的webpack Module Federation配置缺失
library声明:原有可用配置中远程应用声明了library: {type: "var", name: "dashboards"},调整配置后删除了这一行,导致远程应用打包出的remoteEntry.js不会将模块实例挂载到全局变量dashboards上,宿主应用加载后无法识别对应模块实例。 - 宿主应用的remotes配置未匹配远程模块的暴露格式:你使用的
模块名@远程地址格式属于基于全局变量的script类型远程引用,需要明确指定远程加载类型,webpack无法自动识别时就会把配置字符串原样输出到打包产物中,才会出现module.exports = dashboards@http://xxx这种包含非法@字符的JS语法错误。
修复方案
方案1:最小改动修复,保持全局变量挂载模式
- 恢复远程应用的
library配置,同时建议保留shared配置避免多份依赖实例运行报错:
// remote webpack配置 { name: "dashboards", // 加回library配置,确保远程模块挂载到全局变量 library: {type: "var", name: "dashboards"}, filename: "remoteEntry.js", remotes: {}, exposes: { Header: "./src/Header.jsx", }, shared: ["react", "react-dom"] }
- 调整宿主应用的remotes配置,添加
script!前缀明确告诉webpack该资源需要动态加载:
// host webpack配置 { name: "app-shell", filename: "remoteEntry.js", remotes: { dashboards: "script!dashboards@http://localhost:8002/remoteEntry.js", }, shared: ["react", "react-dom"] }
方案2:运行时动态加载(支持动态切换远程地址)
如果需要在运行时灵活控制远程模块的加载时机和地址,可以不用在webpack配置中写死远程声明,直接在业务代码中动态加载:
- 先按照方案1的要求配置好远程应用的
library和shared项。 - 宿主应用删除webpack配置中remotes的
dashboards声明,在需要使用远程组件的位置加入动态加载逻辑:
// 宿主应用中加载远程Header组件的逻辑 const loadRemoteHeader = async () => { // 动态创建script标签加载remoteEntry await new Promise((resolve, reject) => { const script = document.createElement('script'); script.src = 'http://localhost:8002/remoteEntry.js'; script.onload = resolve; script.onerror = reject; document.head.appendChild(script); }); // 从全局变量获取远程模块容器 const container = window.dashboards; // 加载暴露的Header模块 const factory = await container.get('./Header'); const Header = factory(); return Header; }
内容的提问来源于stack exchange,提问作者Raskolnikov
相关产品推荐
相关产品推荐

