目录

一、什么是qiankun

二、应用

主应用 vue3+Ts+vite

子应用1 vue2+webpack

子应用2 Vue3+webpack

子应用3 vue3+vite+Ts

三、结果 

 


一、什么是qiankun

微前端 qiankun 是一个基于 Single-SPA 框架开发的、开源的微前端实现库,由蚂蚁金服(现蚂蚁集团)团队开发和维护。它的目标是为开发者提供一套简单、强大且生产可用的解决方案,帮助构建大型单页应用或聚合多个独立前端应用,无视框架限制React、Vue、Angular 等。

二、应用

主应用 vue3+Ts+vite

主应用是所以子应用的出口,也可以说是一个容器。在各个子应用中起着协调、布局的作用。可以React、Vue、Angula框架作为主应用的框架。

这里主应用就使用Vu3+Ts+vite作为主应用的项目框架,首先初始一个主应用项目:

npm create vite@latest

安装路由:

npm i vue-router -S

主应用必须安装 qiankun 

npm i qiankun -S

注册子应用:main.ts

import { createApp } from 'vue';
import './style.css';
import App from './App.vue';
import router from './router';

// 引入qiankun
import { registerMicroApps, start } from 'qiankun';
// 进行子应用的注册
registerMicroApps([
  {
    name: 'son-vue2', // 取自子应用 package.json 文件中的name属性,必填
    entry: '//localhost:3001', // 子应用端口
    container: '#qiank-container', // 子应用挂载的dom
    activeRule: '/vue2', // 子应用的路由入口
    props: {} // 传给子应用的数据,可以传递一些主应用初始化全局性的数据,比如语言、全局配置,其他数据的传递后续咱们使用发布订阅的形式来完成
  },

  {
    name: 'son-vue3-webpack',
    entry: '//localhost:3002',
    container: '#qiank-container',
    activeRule: '/vue3-webpack',
    props: {}
  },
  {
    name: 'son-vue3-vite',
    entry: '//localhost:3003',
    container: '#qiank-container',
    activeRule: '/vue3-vite',
    props: {}
  }
]);

start({
  sandbox: {
    //启用沙箱样式隔离
    experimentalStyleIsolation: true
  }
});

createApp(App).use(router).mount('#app');

子应用的入口可以随意给我这里直接写在App.vue的文件了

<template>
  <div>
    <router-link to="/vue2">子应用(vue2)</router-link>
    |
    <router-link to="/vue3-webpack">子应用(vue3-webpack)</router-link>
    |
    <router-link to="/vue3-vite">子应用(vue3-vite)</router-link>
  </div>

  <h1>以下为子应用内容:</h1>
  <!-- qiank-container这个必须跟注册时候的一直 -->
  <div id="qiank-container"></div>
</template>

主应用配置完成

子应用1 vue2+webpack

vue2

创建项目

vue create son-vue2

 修改 vue.config.js

const { defineConfig } = require('@vue/cli-service');
const { name } = require('./package.json');

module.exports = defineConfig({
  transpileDependencies: true,
  devServer: {
    port: 3001, //与主应用的注册端口号一直
    headers: {
      'Access-Control-Allow-Origin': '*' //设置为允许跨域
    }
  },
  configureWebpack: {
    output: {
      library: `${name}-[name]`,
      libraryTarget: 'umd', //设置umd格式
      // webpack 5 需要把 jsonpFunction 替换成 chunkLoadingGlobal
      chunkLoadingGlobal: `webpackJsonp_${name}`
    }
  }
});

 新建 src/public-path.js 文件

if (window.__POWERED_BY_QIANKUN__) {
  //以下注释是为了避开eslint报错
  // eslint-disable-next-line no-undef
  __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}

 修改 main.js 文件,qiankun 要求子应用在其入口文件中正确导出特定的生命周期函数,其实就是要导出这三个函数:bootstrap/mount/unmount

import './public-path.js';
import Vue from 'vue';
import App from './App.vue';

Vue.config.productionTip = false;

let instance = null;

function render(props = {}) {
  console.log('子应用(vue2)', props);
  const { container } = props;
  instance = new Vue({
    render: h => h(App)
  }).$mount(container ? container.querySelector('#app') : '#app');
}

// 非qiankun环境下,也能独立运行时
if (!window.__POWERED_BY_QIANKUN__) {
  render();
}

/**
 * bootstrap 只会在微应用初始化的时候调用一次,下次微应用重新进入时会直接调用 mount 钩子,不会再重复触发 bootstrap。
 * 通常我们可以在这里做一些全局变量的初始化,比如不会在 unmount 阶段被销毁的应用级别的缓存等。
 */
export async function bootstrap() {}
/**
 * 应用每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法
 */
export async function mount(props) {
  render(props);
}
/**
 * 应用每次 切出/卸载 会调用的方法,通常在这里我们会卸载微应用的应用实例
 */
export async function unmount() {
  instance.$destroy();
  instance.$el.innerHTML = '';
  instance = null;
}

子应用2 Vue3+webpack

修改 vue.config.js:跟vue2一样

const { defineConfig } = require('@vue/cli-service');
const { name } = require('./package.json');

module.exports = defineConfig({
  transpileDependencies: true,
  devServer: {
    port: 3002,
    headers: {
      'Access-Control-Allow-Origin': '*'
    }
  },
  configureWebpack: {
    output: {
      library: `${name}-[name]`,
      libraryTarget: 'umd',
      // webpack 5 需要把 jsonpFunction 替换成 chunkLoadingGlobal
      chunkLoadingGlobal: `webpackJsonp_${name}`
    }
  }
});

新建 src/public-path.js 文件: 

if (window.__POWERED_BY_QIANKUN__) {
  //以下注释是为了避开eslint报错
  // eslint-disable-next-line no-undef
  __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}

修改 main.js 文件

import './public-path.js';
import { createApp } from 'vue';
import App from './App.vue';

let appInstance = null;

/**
 * 渲染主应用或微应用
 * @param {Object} props - 微应用传递的 props(如 container)
 */
const render = (props = {}) => {
  const { container } = props;
  const mountTarget = container?.querySelector('#app') || '#app';

  try {
    appInstance = createApp(App);
    appInstance.mount(mountTarget);
  } catch (error) {
    console.error('渲染失败:', error);
  }
};

/**
 * 微应用生命周期:初始化(仅一次)
 */
export async function bootstrap() {
  console.log('[微应用] bootstrap');
}

/**
 * 微应用生命周期:挂载(每次进入调用)
 */
export async function mount(props) {
  console.log('[微应用] mount', props);
  render(props);
}

/**
 * 微应用生命周期:卸载(每次切出调用)
 */
export async function unmount() {
  if (appInstance) {
    appInstance.unmount(); // Vue 3 使用 unmount 替代 $destroy
    appInstance._container.innerHTML = ''; // 清理 DOM 残留
    appInstance = null;
    console.log('[微应用] unmount 完成');
  }
}

// 独立运行(非 qiankun 环境)
if (!window.__POWERED_BY_QIANKUN__) {
  render();
}

子应用3 vue3+vite+Ts

启动项目:

npm create vite@latest

安装 vite-plugin-qiankun 依赖,它能帮助咱们快速接入 qiankun 环境:

npm install vite-plugin-qiankun -D

修改mian.ts

import { createApp } from 'vue';
import './style.css';
import App from './App.vue';
import {
  renderWithQiankun,
  qiankunWindow
} from 'vite-plugin-qiankun/dist/helper';
let app: any = undefined;

const render = (props: any) => {
  console.log('子应用(son-vue3-vite)', props);
  const { container } = props;
  app = createApp(App);
  app.mount(container ? container.querySelector('#app') : '#app');
};

const initQianKun = () => {
  renderWithQiankun({
    bootstrap() {},
    mount(props) {
      render(props);
    },
    unmount() {
      app.unmount();
    },
    update() {}
  });
};

qiankunWindow.__POWERED_BY_QIANKUN__ ? initQianKun() : render({});

三、结果 

 

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐