Vite作为Host、CRA作为Remote的Module Federation构建部署异常问题咨询
看起来你已经把Vite Host + CRA Remote的Module Federation基础架子搭起来了,开发环境能跑但生产构建后就炸了,还碰到了Uncaught TypeError: lib.init is not a function这个头疼的错误——我之前在做CRA+Module Federation生产部署时也踩过几乎一模一样的坑,咱们一步步拆解解决:
先聊错误根源
这个lib.init is not a function本质是Vite Host没法正确解析CRA Remote的生产构建产物,核心原因通常是两个:
- CRA默认的构建输出格式和Module Federation要求的UMD模块格式不兼容,导致Host找不到Remote的初始化入口
- 共享依赖的
eager: true配置在生产环境打破了Module Federation的异步加载逻辑
具体修复步骤
1. 补全CRA Remote的craco配置(最关键的一步)
你当前的craco配置里少了webpack output的library声明,CRA默认不会生成UMD格式的产物,而Module Federation的Remote必须是UMD格式才能被Vite正确识别。同时调整共享依赖的eager配置:
替换你的craco.config.js为下面的版本:
const { ModuleFederationPlugin } = require("webpack").container; // 引入package.json自动匹配依赖版本 const packageJson = require('./package.json'); module.exports = { devServer: (devServerConfig) => { devServerConfig.headers = { 'Access-Control-Allow-Origin': '*', // 开发环境跨域保留 }; return devServerConfig; }, webpack: { configure: (webpackConfig) => { // 新增:指定输出为UMD格式,让Vite能正确解析Remote的模块 webpackConfig.output.library = { name: "remoteApp", type: "umd", }; webpackConfig.plugins.push( new ModuleFederationPlugin({ name: "remoteApp", filename: "remoteEntry.js", exposes: { "./App": "./src/App", }, shared: { // 移除eager: true,生产环境不需要提前加载依赖 react: { singleton: true, requiredVersion: packageJson.dependencies.react }, "react-dom": { singleton: true, requiredVersion: packageJson.dependencies["react-dom"] }, }, }) ); return webpackConfig; }, }, };
为什么要移除eager: true?这个配置是给开发环境热更新用的,生产构建下会让React依赖提前加载,直接打乱Module Federation的异步加载流程,导致初始化函数丢失。
2. 修正CRA Remote的生产启动命令
CRA的build产物在build文件夹,用serve启动时必须指定单页应用模式和正确的目录,否则资源路径会完全错乱:
# 先重新构建Remote craco build # 用serve启动,-s是单页应用模式,-l指定端口避免和Host冲突 serve -s build -l 3001
如果直接serve不指定-s build,serve会在当前目录找静态文件,根本找不到build文件夹里的资源,自然加载不出UI。
3. 检查Vite Host的配置
确保Vite Host的Module Federation配置里,Remote的地址是正确的生产环境地址,比如Remote跑在http://localhost:3001,那vite.config.js里的配置要对应:
// vite.config.js import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import federation from '@originjs/vite-plugin-federation' export default defineConfig({ plugins: [ react(), federation({ name: 'hostApp', remotes: { // 注意是Remote的远程入口文件绝对地址 remoteApp: 'http://localhost:3001/remoteEntry.js', }, shared: { react: { singleton: true }, 'react-dom': { singleton: true }, } }) ], })
另外Vite Host构建后启动时,尽量用vite preview而不是第三方serve工具,避免路径解析问题:
npm run build vite preview --port 3000
4. 验证暴露模块的导出格式
确保CRA Remote里src/App.js是默认导出:
// src/App.js function App() { return <div>My Remote App</div> } export default App
然后Vite Host里导入时要对应默认导入:
// Host里的组件 import RemoteApp from 'remoteApp/App' function HostApp() { return ( <div> <h1>Vite Host</h1> <RemoteApp /> </div> ) }
如果是命名导出,两边的导入导出要严格对应,不然也会出现加载异常。
最后验证流程
按这个顺序操作:
- 重启CRA Remote的构建和服务:
craco build→serve -s build -l 3001 - 重启Vite Host的构建和预览:
npm run build→vite preview --port 3000 - 打开浏览器访问
http://localhost:3000,同时打开开发者工具的Network和Console面板,确认remoteEntry.js和App的资源都返回200,没有报错。
如果还是有问题,先看Console里有没有其他前置错误(比如依赖版本不匹配),再看Network里的资源路径是否正确——大概率是路径或者依赖版本的小问题,调整下就能解决。




