qiankun 微前端集成子项目

场景一:常规子应用接入(基于 Umi/Webpack)

在这个场景中,主应用和子应用通常都是基于 UmiJS 或标准的 Webpack 构建。

1. 主应用配置

主应用需要在路由中注册子应用,并在配置文件中指明子应用的真实访问地址(区分开发环境和生产环境)。

路由配置 (routes.ts)

添加子应用的路由匹配规则,注意路径后面的 /* 是必须的:

typescript 复制代码
export default[
  // ...其他路由
  {
    path: '/iocPage/*',
    name: 'ioc大屏',
    layout: false,
    microApp: 'app1', // 这里的 microApp 名字必须与下面 config 中配置的 name 保持一致
    microAppProps: {
      autoSetLoading: true,
    },
  },
];

开发环境配置 (config.develop.ts)

开发环境下,entry 直接指向子应用本地启动的服务地址:

typescript 复制代码
import { defineConfig } from 'umi';

export default defineConfig({
  qiankun: {
    slave: {},
    master: {
      apps:[
        {
          name: 'app1',
          entry: 'http://192.168.2.12:8111' // 子应用本地测试环境地址
        }
      ],
    },
  },
});

生产环境配置 (config.production.ts)

生产环境下,entry 通常指向 Nginx 或后端的代理路径:

typescript 复制代码
import { defineConfig } from 'umi';

export default defineConfig({
  qiankun: {
    slave: {},
    master: {
      apps:[
        {
          name: 'app1',
          entry: '/ioc/'  // 生产环境的后端/Nginx代理路径
        }
      ],
    },
  },
});

访问地址演示: 部署后,通过 http://192.168.2.120:9080/iocPage/home 即可访问该子应用。


2. 子应用(app1)配置

基础配置 (config.ts)

开启 qiankun 插件支持:

typescript 复制代码
import { defineConfig } from 'umi';

export default defineConfig({
  base: '/',
  qiankun: {
    slave: {},
    master: {}
  }
});

生产环境配置 (config.production.ts)

由于生产环境主应用通过 /ioc/ 代理访问子应用资源,因此必须配置 publicPath

typescript 复制代码
import { defineConfig } from 'umi';

export default defineConfig({
  // publicPath 需同主应用 config.production.ts 中的 entry 保持一致
  publicPath: '/ioc/', 
});

项目配置 (package.json)

确保项目名称配置正确,这会作为 qiankun 识别的标识之一:

json 复制代码
{
  "name": "ioc"
}

场景二:Vite 项目作为子应用接入

由于 Vite 默认的 ESM 模块加载方式与 Qiankun 目前基于代码包裹的沙箱机制存在冲突,因此接入 Vite 子应用需要借助 vite-plugin-qiankun 插件。

1. 主应用配置增加 Vite 子应用

与场景一类似,主应用仍需增加路由和应用注册信息。

路由配置:

typescript 复制代码
{
  path: '/policyMatchPage/*',
  name: '政策匹配',
  layout: false,
  microApp: 'app2',
  microAppProps: {
    autoSetLoading: true,
  },
}

主应用注册配置:

typescript 复制代码
qiankun: {
  slave: {},
  master: {
    apps:[
      // ...之前的 app1
      {
        name: 'app2',
        entry: '/policyMatch' // 生产环境后端代理路径
      }
    ],
  },
}

2. Vite 子应用(app2)配置

首先需要安装对应的插件:

bash 复制代码
npm install vite-plugin-qiankun qiankun -S

Vite 构建配置 (vite.config.js)

需要引入插件、配置跨域、并修改 build 产物格式:

javascript 复制代码
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import md from 'vite-plugin-md';
import qiankun from 'vite-plugin-qiankun';

export default defineConfig({
  // 生产环境配置为代理路径,开发环境为 '/'
  base: process.env.NODE_ENV === 'production' ? '/policyMatch/' : '/',
  plugins:[
    vue({
      include: [/\.vue$/, /\.md$/], // 让 Vite 处理 .md 文件
    }),
    md(),
    // 'app2' 必须与主应用注册的 name 一致
    qiankun('app2', { 
      useDevMode: true
    }),
  ],
  server: {
    port: 5173,
    cors: true, // 必须开启跨域,主应用才能动态 fetch 拉取资源
    origin: 'http://localhost:5173',
    headers: {
      'Access-Control-Allow-Origin': '*',
    },
  },
  build: {
    rollupOptions: {
      output: {
        format: 'umd' // 配合 qiankun 的模块加载
      }
    }
  },
});

入口文件修改 (main.js)

Vite 子应用不再通过导出生命周期函数的方式,而是通过 renderWithQiankun 进行生命周期的劫持和渲染:

javascript 复制代码
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import { renderWithQiankun, qiankunWindow } from 'vite-plugin-qiankun/dist/helper';

let app = null;

function render(props = {}) {
  const { container } = props;
  app = createApp(App);
  app.use(router);
  // 判断是作为子应用挂载到主应用 DOM 内,还是独立运行
  app.mount(container ? container.querySelector('#app') : '#app');
}

// 核心:判断是否在 Qiankun 环境内
if (qiankunWindow.__POWERED_BY_QIANKUN__) {
  renderWithQiankun({
    bootstrap() {
      console.log('===qiankun bootstrap===');
    },
    mount(props) {
      console.log('===qiankun mount===', props);
      render(props);
    },
    unmount(props) {
      console.log('===qiankun unmount===');
      if (app) {
        app.unmount();
        app = null;
      }
    },
    update(props) {
      console.log('===qiankun update===');
    }
  });
} else {
  // 独立运行
  render();
}

路由配置修改 (router.js)

Vue Router 的 history 模式需要根据环境动态设置 base 路径:

javascript 复制代码
import { createRouter, createWebHistory } from "vue-router";
import { qiankunWindow } from "vite-plugin-qiankun/es/helper";
import routes from './routes'; // 你的路由表

const router = createRouter({
  // 当在微前端环境下时,基础路径需设为主应用中配置的路由路径
  history: createWebHistory(
    qiankunWindow.__POWERED_BY_QIANKUN__ ? '/policyMatchPage/' : '/'
  ),
  routes
});

export default router;

💡 总结与避坑指南

  1. 路由与 PublicPath 对应关系 :主应用的路由 Path(例如 /iocPage/*)决定了子应用 Router 的 base;而主应用的 entry 代理地址(例如 /ioc/)决定了子应用构建时的 publicPath 或 Vite 的 base。这两者不要混淆。
  2. Vite 接入的坑 :原生 Qiankun 对 Vite 的支持不完善,千万不要忘了引入 vite-plugin-qiankun 并按需调整入口文件生命周期的写法。
  3. 跨域问题 :子应用的 server 配置中一定要加上 cors: true 以及 Access-Control-Allow-Origin: '*',否则主应用在开发环境下 fetch 子应用资源会报跨域错误。
相关推荐
Hello--_--World1 小时前
React:useRef 超详细教程、forwardRef 详解、useImperativeHandle详解
前端·javascript·react.js
xuankuxiaoyao1 小时前
vue.js 课程自己编写小游戏
前端·javascript·vue.js
天一生水water1 小时前
VUE3入门
javascript
yqcoder2 小时前
JavaScript 浅拷贝:只复制“第一层”的艺术
开发语言·javascript·ecmascript
yqcoder2 小时前
JavaScript 闭包:函数背后的“背包”
开发语言·javascript·ecmascript
threelab2 小时前
挑战AI辅助从零构建3D模型编辑器:01基于Vue3 + Three.js的现代化架构设计
javascript·人工智能·3d·前端框架·着色器
张元清2 小时前
React 浏览器标签页 UX:用标题、Favicon 和通知把用户拉回来
前端·javascript·面试
葛兰岱尔2 小时前
葛兰岱尔rapid3D Loader for Three.js使用方式及7个基础API说明
开发语言·javascript·3d
Lkstar2 小时前
读完红宝书和YDKJS,我终于搞懂了原型链、闭包和this
javascript·面试