Vue Bridge(for Vue v3)

@module-federation/bridge-vue3 提供了用于 Vue V3 应用的 bridge 工具函数,其提供的 createBridgeComponent 可用于导出应用级别模块,createRemoteAppComponent 用于加载应用级别模块。Demo

安装

npm
yarn
pnpm
npm install @module-federation/bridge-vue3@latest

类型

function createRemoteAppComponent<T, E extends keyof T>(
  options: {
    // Function to load remote application, e.g., loadRemote('remote1/export-app') or import('remote1/export-app')
    loader: () => Promise<T>;
    // Default is 'default', used to specify module export
    export?: E;
    // Parameters that will be passed to defineAsyncComponent
    asyncComponentOptions?: Omit<AsyncComponentOptions, 'loader'>;
    // Attributes that will be bound to the root container where the remote Vue application will be mounted
    rootAttrs?: Record<string, unknown>;
    // 使用 memory history 进行隔离路由(例如在弹窗或沙箱中渲染)
    memoryRoute?: { entryPath: string };
    // 使用 hash 路由模式代替默认的 web history
    hashRoute?: boolean;
  }
): (props: {
    basename?: string;
    memoryRoute?: { entryPath: string };
}) => DefineComponent;


function createBridgeComponent(bridgeInfo: {
  rootComponent: VueComponent;
  appOptions?: (params: {
    app: Vue.App<VueComponent>;
    basename?: string;
    memoryRoute?: { entryPath: string };
    hashRoute?: boolean;
    [key: string]: any;
  }) => { router?: Router } | void;
}): () => {
  render(info: {
    name?: string;
    basename?: string;
    memoryRoute?: {
      entryPath: string;
    };
    hashRoute?: boolean;
    dom?: HTMLElement;
  }): void;
  destroy(info: {
    dom: HTMLElement;
  }): void;
}

示例

Remote

// ./src/export-app.ts
import App from './App.vue';
import router from './router';
import customPlugin from './plugins/custom-vue-plugin';
import { createBridgeComponent } from '@module-federation/bridge-vue3';

export default createBridgeComponent({
  rootComponent: App,
  appOptions: ({ app }) => {
    // Optional: adding a plugin to the new Vue instance on the host application side
    app.use(customPlugin);
    return { router };
  },
});
// rsbuild.config.ts
import { pluginModuleFederation } from '@module-federation/rsbuild-plugin';

export default defineConfig({
  plugins: [
    pluginModuleFederation({
      name: 'remote1',
      exposes: {
        './export-app': './src/export-app.ts',
      },
      shared: ['vue', 'vue-router'],
    }),
  ],
});

Host

//rsbuild.config.ts
import { pluginModuleFederation } from '@module-federation/rsbuild-plugin';

export default defineConfig({
  plugins: [
    pluginModuleFederation({
      name: 'host',
      remotes: {
        remote1: 'remote1@http://localhost:2001/mf-manifest.json',
      },
    }),
  ],
});
// ./src/router.ts
import * as bridge from '@module-federation/bridge-vue3';

const Remote1 = bridge.createRemoteAppComponent({
  loader: () => loadRemote('remote1/export-app'),
});

const router = createRouter({
  history: createWebHistory(),
  routes: [
    // 在这里定义你的路由
    { path: '/', component: Home },
    { path: '/remote1/:pathMatch(.*)*', component: Remote1 },
    // 其他路由
  ],
});
export default router;

路由模式

Bridge 支持三种路由模式,决定远程应用如何管理其内部导航:

模式配置项History 类型使用场景
Web History(默认)createWebHistory(basename)标准的基于 URL 的路由。basename 会自动从宿主路由匹配中获取。
Memory HistorymemoryRoute: { entryPath: '/path' }createMemoryHistory(basename)隔离路由,不会影响浏览器 URL。适用于远程应用在弹窗、侧边栏或沙箱中渲染的场景。
Hash HistoryhashRoute: truecreateWebHashHistory()基于 hash 的路由(#/path)。路由路径会自动添加 basename 前缀。

Hash 路由示例

// ./src/router.ts
import * as bridge from '@module-federation/bridge-vue3';

const Remote1 = bridge.createRemoteAppComponent({
  loader: () => loadRemote('remote1/export-app'),
  hashRoute: true,
});

const router = createRouter({
  history: createWebHashHistory(),
  routes: [
    { path: '/', component: Home },
    { path: '/remote1/:pathMatch(.*)*', component: Remote1 },
  ],
});
export default router;

Memory 路由示例

// ./src/router.ts
import * as bridge from '@module-federation/bridge-vue3';

const Remote1 = bridge.createRemoteAppComponent({
  loader: () => loadRemote('remote1/export-app'),
  memoryRoute: { entryPath: '/initial-page' },
});

const router = createRouter({
  history: createWebHistory(),
  routes: [
    { path: '/', component: Home },
    { path: '/remote1/:pathMatch(.*)*', component: Remote1 },
  ],
});
export default router;

方法

createRemoteAppComponent

function createRemoteAppComponent<T, E extends keyof T>(
  options: {
    // Function to load remote application, e.g., loadRemote('remote1/export-app') or import('remote1/export-app')
    loader: () => Promise<T>;
    // Default is 'default', used to specify module export
    export?: E;
    // Parameters that will be passed to defineAsyncComponent
    asyncComponentOptions?: Omit<AsyncComponentOptions, 'loader'>;
    // Attributes that will be bound to the root container where the remote Vue application will be mounted
    rootAttrs?: Record<string, unknown>;
    // 使用 memory history 进行隔离路由(例如在弹窗或沙箱中渲染)
    memoryRoute?: { entryPath: string };
    // 使用 hash 路由模式代替默认的 web history
    hashRoute?: boolean;
  }
): (props: {
    basename?: string;
    memoryRoute?: { entryPath: string };
}) => DefineComponent;
const Remote1App = createRemoteAppComponent({ loader: () => loadRemote('remote1/export-app') });
  • options
    • loader
      • type: () => Promise<Module>
      • Purpose: Used to load remote modules, e.g., loadRemote('remote1/export-app') or import('remote1/export-app')
    • export
      • type: string
      • Purpose: Used to specify module export
    • asyncComponentOptions
      • type: Omit<AsyncComponentOptions, 'loader'>
      • Purpose: Parameters that will be passed to defineAsyncComponent, except for the loader parameter
    • rootAttrs
      • type: Record<string, unknown>
      • Purpose: Attributes that will be bound to the root container where the remote Vue application will be mounted
    • memoryRoute
      • type: { entryPath: string }
      • 用途:提供后,远程应用将使用 memory history(createMemoryHistory)代替默认的 web history。entryPath 设置远程应用挂载时导航到的初始路由。适用于远程应用在隔离上下文(例如弹窗或沙箱)中渲染且不应修改浏览器 URL 的场景。
    • hashRoute
      • type: boolean
      • 用途:设为 true 时,远程应用将使用基于 hash 的 history(createWebHashHistory)代替默认的 web history。路由路径会自动添加 basename 前缀。当宿主应用也使用 hash 路由时使用此选项。
// remote
export const provider = createBridgeComponent({
  rootComponent: App
});

// host
const Remote1App = createRemoteAppComponent({
  loader: () => loadRemote('remote1/export-app'),
  export: 'provider'
});
  • ReturnType
    • type: VueComponent
    • Purpose: Used to render remote module components
import * as bridge from '@module-federation/bridge-vue3';

const Remote2 = bridge.createRemoteAppComponent({ loader: () => loadRemote('remote1/export-app'), rootAttrs: {class: 'root-element-class'} });

const router = createRouter({
  history: createWebHistory(),
  routes: [
    // Define your routes here
    { path: '/', component: Home },
    { path: '/remote1/:pathMatch(.*)*', component: Remote2, props: { foo: 'bar' } },
    // Other routes
  ],
});
export default router;

createBridgeComponent

function createBridgeComponent(bridgeInfo: {
  rootComponent: VueComponent;
  appOptions?: (params: {
    app: Vue.App<VueComponent>;
    basename?: string;
    memoryRoute?: { entryPath: string };
    hashRoute?: boolean;
    [key: string]: any;
  }) => { router?: Router } | void;
}): () => {
  render(info: {
    name?: string;
    basename?: string;
    memoryRoute?: {
      entryPath: string;
    };
    hashRoute?: boolean;
    dom?: HTMLElement;
  }): void;
  destroy(info: { dom: HTMLElement }): void;
}
  • bridgeInfo
    • type: { rootComponent: VueComponent; appOptions?: (params: AddOptionsFnParams) => ({ router?: Router }) }
    • 用途:用于传递根组件
    • appOptions 接收以下参数:
      • app:Vue 应用实例
      • basename:从宿主路由获取的基础路径
      • memoryRoute:memory 路由配置(如果宿主提供)
      • hashRoute:是否启用 hash 路由(如果宿主提供)
  • ReturnType
    • type: () => { render: (info: RenderFnParams) => void; destroy: (info: { dom: HTMLElement}) => void; }
// ./src/export-app.ts
import  { createBridgeComponent } from '@module-federation/bridge-vue3';
import App from './App.vue';
import customPlugin from './plugins/custom-vue-plugin';
import router from './router';

export default createBridgeComponent({
  rootComponent: App,
  appOptions: ({ app }) => {
    // Optional: adding a plugin to the new Vue instance on the host application side
    app.use(customPlugin);
    return { router };
  },
});