Repack React Native Module Federation V2动态远程加载失败求助
问题
在Repack.plugins.ModuleFederationPluginV2中配置动态远程模块加载时,无法在原生App中加载脚本,相关配置代码如下:
remotes: { App: `promise new Promise(resolve => { fetch('http://192.168.0.102:3000/config') .then(res => res.json()) .then(data => { const { remoteName, url } = data; console.log(data); if (!remoteName || !url) { throw new Error('Invalid remote config'); } fetch(url) .then(response => response.text()) .then(code => { const script = new Function(code); script(); resolve(globalThis[data.remoteName]); }) .catch(error => console.error('Error loading remote:', error)); }) .catch(error => console.error('Error fetching config:', error)); })`, },
API响应内容:
{ "config": { "name": "micro-version-url", "remoteName": "App1", "url": "http://192.168.0.102:9002/android/app1.container.js.bundle" } }
解决方案
1. 修复API响应取值路径
API返回的remoteName和url嵌套在config字段下,但原代码直接从data根对象取值,会导致这两个值为undefined,触发错误。修改取值逻辑:
const { remoteName, url } = data.config;
2. 替换脚本执行方式
原生App环境中new Function执行代码可能遇到安全限制或兼容性问题,改用标准的<script>标签加载方式:
fetch(url) .then(response => response.text()) .then(code => { const script = document.createElement('script'); script.textContent = code; document.head.appendChild(script); script.onload = () => { resolve(window[remoteName]); }; script.onerror = (error) => { console.error('Error loading remote script:', error); reject(error); }; })
3. 兼容全局对象引用
部分原生WebView对globalThis支持不佳,替换为window更稳妥:
resolve(window[remoteName]);
4. 完善错误处理
补充远程模块不存在的判断,避免无意义的resolve:
script.onload = () => { const remoteModule = window[remoteName]; if (!remoteModule) { reject(new Error(`Remote module ${remoteName} not found in global scope`)); return; } resolve(remoteModule); };
完整修正后的配置代码
remotes: { App: `promise new Promise((resolve, reject) => { fetch('http://192.168.0.102:3000/config') .then(res => res.json()) .then(data => { const { remoteName, url } = data.config; console.log('Remote config:', data.config); if (!remoteName || !url) { throw new Error('Invalid remote config: missing remoteName or url'); } fetch(url) .then(response => response.text()) .then(code => { const script = document.createElement('script'); script.textContent = code; document.head.appendChild(script); script.onload = () => { const remoteModule = window[remoteName]; if (!remoteModule) { reject(new Error(`Remote module "${remoteName}" not registered in global scope`)); return; } resolve(remoteModule); }; script.onerror = (error) => { reject(new Error(`Failed to load remote script: ${error.message}`)); }; }) .catch(error => { console.error('Error fetching remote script:', error); reject(error); }); }) .catch(error => { console.error('Error fetching config:', error); reject(error); }); })`, },
内容的提问来源于stack exchange,提问作者Kiran B
相关产品推荐
相关产品推荐

