You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否通过Module Federation在React 17中挂载Vue 2应用?

Vue 2 微前端挂载到 React 17 宿主应用报错解决方案

问题背景

将 Vue CLI 5 生成的 Vue 2 应用(含2个默认路由)通过 Module Federation 挂载到 React 17 宿主应用时,已成功获取 remoteEntry.js,但挂载时触发错误:

error Error: Module "." does not exist in container. while loading "." from webpack/container/reference/@zx-mfe/vueRemote

相关配置

Vue 端 vue.config.js Module Federation 配置

module.exports = defineConfig({
  transpileDependencies: true,
  configureWebpack: {
    devServer: {
      historyApiFallback: true
    },
    optimization: {
      splitChunks: false
    },
    plugins: [
      new ModuleFederationPlugin({
        name: 'vueRemote',
        filename: 'remoteEntry.js',
        exposes: {
          './sharedApp': './src/expose.ts'
        }
      })
    ]
  }
})

Vue 暴露文件 src/expose.ts

//app content
// export default new Vue({
//   router,
//   render: h => h(App)
// }).$mount('#app')

import app from './main'

export default app

React 端 Module Federation 配置

new ModuleFederationPlugin({
        name: "host",
        remotes: {
          "@zx-mfe/vueRemote": "vueRemote@http://localhost:8080/remoteEntry.js",
        },
      }),

React 挂载 Vue 应用的 Loader 组件

import React from 'react';
import { ErrorBoundary } from 'react-error-boundary';

//@ts-ignore
const VueApp = React.lazy(() => import("@zx-mfe/vueRemote")
.then((res) => {
  console.log('res', res)
})
.catch((error) => {
  console.log('error', error)
}));

export const VueAppLoader = () => {
  return (
    <React.Suspense fallback="loading">
      <ErrorBoundary fallback={<h2>Failed to load Vue Application</h2>}>
        <VueApp />
      </ErrorBoundary>
    </React.Suspense>
  )
}

问题分析与解决步骤

核心问题定位

报错根源是模块引入路径不匹配:Vue 端暴露的是 ./sharedApp 子路径,但 React 端直接请求了远程模块的根路径 .,而容器中并未暴露根路径模块,导致找不到资源。

步骤1:修正 React 端的模块引入路径

将 React 组件中的 import 路径改为 Vue 端暴露的具体模块路径,并处理 Vue 实例到 React 组件的转换:

import React from 'react';
import { ErrorBoundary } from 'react-error-boundary';

//@ts-ignore
const VueApp = React.lazy(() => import("@zx-mfe/vueRemote/sharedApp")
.then((vueInstance) => {
  // 返回适配 React 的组件,通过容器挂载 Vue 实例
  return {
    default: () => {
      const containerRef = React.useRef<HTMLDivElement>(null);

      React.useEffect(() => {
        if (containerRef.current && vueInstance.default) {
          // 挂载 Vue 实例到容器
          vueInstance.default.$mount(containerRef.current);
          // 卸载时清理 Vue 实例,避免内存泄漏
          return () => vueInstance.default.$destroy();
        }
      }, [vueInstance.default]);

      return <div ref={containerRef}></div>;
    }
  };
})
.catch(() => {
  return {
    default: () => <h2>Failed to load Vue Application</h2>
  };
}));

export const VueAppLoader = () => {
  return (
    <React.Suspense fallback="loading">
      <ErrorBoundary fallback={<h2>Failed to load Vue Application</h2>}>
        <VueApp />
      </ErrorBoundary>
    </React.Suspense>
  )
}

步骤2:优化 Vue 端的暴露逻辑

确保暴露的是未挂载的 Vue 实例,交给 React 端控制挂载时机:
修改 src/expose.ts:

import Vue from 'vue';
import App from './App.vue';
import router from './router';

// 创建实例但不自动挂载,避免重复挂载问题
export default new Vue({
  router,
  render: h => h(App)
});

步骤3:确认 Vue 2 兼容性说明

Vue 2 完全支持通过 Module Federation 作为微前端子应用挂载到 React 宿主,核心注意点:

  • 必须通过容器元素间接挂载 Vue 实例,不能直接将 Vue 实例作为 React 组件渲染
  • 严格处理 Vue 实例的挂载/卸载生命周期,避免内存泄漏
  • 确保两端 webpack 版本均为 5+(Vue CLI 5 已满足,React 端需对应配置)

额外优化建议

  • 路由隔离:给 Vue 应用设置路由基础路径,避免与 React 宿主路由冲突
    修改 Vue 端 router/index.js:
    const router = new VueRouter({
      mode: 'history',
      base: '/vue-subapp/',
      routes: [...]
    });
    
  • 样式隔离:使用 Vue 的 scoped styles 或 CSS Modules,防止样式污染宿主应用

内容的提问来源于stack exchange,提问作者Verthon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 10:35:17