You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Vite作为Host、CRA作为Remote的Module Federation构建部署异常问题咨询

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的生产构建产物,核心原因通常是两个:

  1. CRA默认的构建输出格式和Module Federation要求的UMD模块格式不兼容,导致Host找不到Remote的初始化入口
  2. 共享依赖的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>
  )
}

如果是命名导出,两边的导入导出要严格对应,不然也会出现加载异常。

最后验证流程

按这个顺序操作:

  1. 重启CRA Remote的构建和服务:craco buildserve -s build -l 3001
  2. 重启Vite Host的构建和预览:npm run buildvite preview --port 3000
  3. 打开浏览器访问http://localhost:3000,同时打开开发者工具的Network和Console面板,确认remoteEntry.js和App的资源都返回200,没有报错。

如果还是有问题,先看Console里有没有其他前置错误(比如依赖版本不匹配),再看Network里的资源路径是否正确——大概率是路径或者依赖版本的小问题,调整下就能解决。

火山引擎 最新活动