使用Promise-based动态远程模块时自引用引发无限循环问题求助
自引用微前端Promise动态远程加载循环问题解决方案
缓存已加载的Remote Entry Promise
核心是避免重复触发remoteEntry的加载逻辑。维护一个全局缓存对象,存储已经resolved的Promise,后续请求直接复用:const remoteCache = new Map(); function getRemoteEntry(remoteName) { if (remoteCache.has(remoteName)) { return remoteCache.get(remoteName); } const promise = new Promise((resolve) => { const script = document.createElement('script'); script.src = `/${remoteName}/remoteEntry.js`; script.onload = () => { resolve(window[remoteName]); }; document.head.appendChild(script); }); remoteCache.set(remoteName, promise); return promise; }同一个remoteName被多次请求时,直接返回缓存的Promise,不会重复加载script标签,从根源上阻断循环。
在Webpack配置中判断自引用场景
当当前应用名称与要加载的remote名称一致时,直接返回自身的暴露模块,跳过remoteEntry加载:const currentAppName = 'home'; module.exports = { // ...其他Webpack配置 plugins: [ new ModuleFederationPlugin({ name: currentAppName, exposes: { './App': './src/App' }, remotes: { home: `promise new Promise(resolve => { if (window['home']) { resolve(window['home']); } else if (window.location.pathname.includes('/home/')) { // 当前为home应用,直接返回自身暴露模块 resolve({ get: (module) => Promise.resolve(require('./src/App')) }); } else { const script = document.createElement('script'); script.src = '/home/remoteEntry.js'; script.onload = () => resolve(window['home']); document.head.appendChild(script); } })` } }) ] };这种方式直接在自引用场景下规避remoteEntry的重复加载触发。
通过共享配置替代自引用逻辑
如果自引用是为了共享模块,可将公共模块抽离到shared配置中,直接import使用,无需通过remote引入自身:new ModuleFederationPlugin({ // ...其他配置 shared: { react: { singleton: true, eager: true }, 'react-dom': { singleton: true, eager: true }, // 添加其他需要共享的模块 } })从设计层面消除自引用循环的可能性。
内容的提问来源于stack exchange,提问作者Notre
相关产品推荐
相关产品推荐

