网站设计标语百度排行榜前十名
在使用 module-federation
中的 loadRemoteModule
时,如果模块加载失败(比如远程应用不可访问、模块不存在、网络问题等),通常会遇到类似 Uncaught (in promise)
的错误。这类错误是 异步的 Promise 错误,因此需要用 try...catch
或 .catch()
来捕捉。
✅ 错误捕捉方式(推荐使用 try...catch
)
如果使用的是 async/await
方式来调用 loadRemoteModule
,可以进行下面的处理:
import { loadRemoteModule } from '@angular-architects/module-federation';async function loadRemote() {try {const module = await loadRemoteModule({type: 'module',remoteEntry: 'http://localhost:3000/remoteEntry.js',exposedModule: './Module'});// 你可以在这里使用 module 了} catch (error) {console.error('远程模块加载失败:', error);// 你也可以在这里处理 UI 提示、fallback 显示等逻辑}
}
✅ 如果使用的是 .then().catch()
方式:
loadRemoteModule({type: 'module',remoteEntry: 'http://localhost:3000/remoteEntry.js',exposedModule: './Module'
}).then((module) => {// 成功加载
}).catch((error) => {console.error('远程模块加载失败:', error);
});
如何捕捉到 remoteEntry.js 404报错
remoteEntry.js
加载失败(比如 404),这个错误无法被loadRemoteModule().catch()
或try...catch
捕捉到。
这是因为:
❗ 404 错误发生在 <script>
标签动态加载时,而不是在 JS Promise 中
module-federation
(或 Angular Architects 的 loadRemoteModule
)在内部使用了动态创建 <script src="...">
的方式加载远程模块,而 <script>
加载失败并不会自动 reject 一个 promise,默认它会触发 onerror
,但这不是 Promise 的异常。
✅ 正确做法:提前检查 remoteEntry 是否可访问(推荐做法)
可以 在调用 loadRemoteModule
之前,先用 fetch
检查 remoteEntry.js
是否存在:
async function safeLoadRemoteModule() {const remoteEntryUrl = 'http://localhost:3000/remoteEntry.js';try {// 提前检查 remoteEntry.js 是否可以访问const res = await fetch(remoteEntryUrl, { method: 'HEAD' });if (!res.ok) throw new Error(`Remote entry not found: ${remoteEntryUrl}`);// 如果检查通过,再加载模块const module = await loadRemoteModule({type: 'module',remoteEntry: remoteEntryUrl,exposedModule: './Module'});return module;} catch (err) {console.error('模块加载失败:', err);// fallback 处理}
}
✅ 另一种高级方案:监听 script 加载错误(适用于动态远程加载)
如果写了 remote 动态加载逻辑(不依赖封装库),可以这样监听:
function loadRemoteEntry(remoteEntryUrl: string): Promise<void> {return new Promise((resolve, reject) => {const script = document.createElement('script');script.src = remoteEntryUrl;script.type = 'text/javascript';script.async = true;script.onerror = () => {reject(new Error(`加载远程入口失败: ${remoteEntryUrl}`));};script.onload = () => {resolve();};document.head.appendChild(script);});
}
🔁 总结
问题 | 为什么捕捉不到 | 推荐解决方式 |
---|---|---|
remoteEntry.js 返回 404 | 是 <script> 的加载错误 | 用 fetch 预检测或手动监听 onerror |
loadRemoteModule 捕不到异常 | Promise 未触发 reject | 在外部做资源可达性检查 |
🔍 常见错误及排查建议:
remoteEntry.js
404:- 检查 URL 是否正确。
- 远程项目是否已经部署或启动。
- CORS 错误:
- 确保远程服务的响应头中设置了合适的
Access-Control-Allow-Origin
。
- 确保远程服务的响应头中设置了合适的
- exposedModule 写错:
- 检查模块暴露名是否和远程项目
webpack.config.js
中的exposes
匹配。
- 检查模块暴露名是否和远程项目
- loadRemoteModule 返回 undefined:
- 可能是模块加载成功,但模块内部没有正确导出。