无需eject的Create React App(CRA)加载外部esmodule方法咨询
无需eject CRA加载远程ESModule组件的可行方案
完全可以实现,不需要执行eject操作,共有3种低侵入的实现方案可选:
方案1:原生ESM动态导入(零配置推荐)
直接利用浏览器原生ESModule加载能力,通过webpack注释让本地构建忽略该导入请求,绕开webpack仅加载本地源码模块的限制,不需要修改任何CRA配置,也不需要安装额外依赖:
import { useState, useEffect, Suspense } from 'react'; // 加载远程ESM组件 const getRemoteComponent = async (remoteUrl) => { // webpackIgnore注释告知webpack不处理该导入,交由浏览器原生处理 const module = await import(/* webpackIgnore: true */ remoteUrl); // 兼容default导出和命名导出 return module.default ?? module; }; function App() { const [RemoteComp, setRemoteComp] = useState(null); useEffect(() => { getRemoteComponent('你的远程组件部署地址/index.esm.js') .then(setRemoteComp); }, []); return ( <div> {RemoteComp && ( <Suspense fallback="组件加载中"> <RemoteComp /> </Suspense> )} </div> ); }
方案2:SystemJS运行时加载
如果需要兼容低版本浏览器,或者需要做模块依赖共享、版本管理,可以用SystemJS作为运行时加载器,同样不需要修改CRA构建配置:
- 先安装依赖:
npm install systemjs - 代码示例:
import SystemJS from 'systemjs'; import { useState, useEffect, Suspense } from 'react'; const getRemoteComponent = async (remoteUrl) => { const module = await SystemJS.import(remoteUrl); return module.default ?? module; }; // 后续使用逻辑和方案1一致
方案3:CRACO覆盖webpack配置
如果需要用模块联邦等更复杂的微前端加载能力,可以用CRACO工具非侵入式修改CRA的webpack配置,不需要eject:
- 安装
@craco/craco依赖,修改package.json中的启动、构建命令为craco对应的指令 - 项目根目录新增
craco.config.js,在配置中开启webpack的ESModule支持、配置模块联邦远程应用映射 - 配置完成后即可直接用标准import语法加载远程微应用注册的组件,和本地组件使用体验完全一致
注意事项
- 远程组件部署的服务器需要配置正确的CORS跨域头,允许宿主域名访问
- 远程组件打包时建议将react、react-dom等公共依赖设置为external,和宿主使用同一份依赖实例,避免多实例引发的上下文丢失、hooks报错等问题
- 若远程组件有样式资源,需要单独处理引入,可在打包时将样式单独导出,宿主加载组件时同步加载远程样式文件
内容的提问来源于stack exchange,提问作者joeCarpenter
相关产品推荐
相关产品推荐

