[qiankun] The specific use of micro-frontends in projects

1. Install qiankun

npm install qiankun --save

2. Register and configure qiankun in the main application

  1. In the entry file main.ts of the main application, introduce the registration method of qiankun:
import {
    
     registerMicroApps, start } from 'qiankun';
  1. Create an array for configuring information about sub-applications. Each sub-application needs to provide a name, entry URL, mount point and some optional configuration items. For example:
const apiEnv = {
    
    
  dev: 'http://localhost:8081/',    // 此处不能使用network,必须用local,不然会报错跨域
  test: 'http://10.11.12.13/api/',
  production: 'http://10.11.12.13/api/'
}

const apps = [
  {
    
    
    name: '子应用1',
    entry: process.env.NODE_ENV === 'development' ? apiEnv.dev : '...根据环境去判断用哪个地址,具体不写了', // 子应用的入口URL
    container: '#subcontainer', // 子应用的挂载点
    activeRule: '/sub-app1', // 子应用的激活规则,就是子应用的公共路径,设置在createHistory里面的那个
  },
  {
    
    
    name: '子应用2',
    entry: 'http://localhost:8082',
    container: '#subcontainer',
    activeRule: '/sub-app2',
  },
  // 其他子应用的配置
];
  1. Call the registerMicroApps method to register sub-applications:
registerMicroApps(apps, {
    
    
	// qiankun 生命周期钩子 - 微应用加载前
	beforeLoad: (app) => {
    
    
		console.log('before load', app.name);
		return Promise.resolve();
	},
	// qiankun 生命周期钩子 - 微应用挂载后
	afterMount: (app) => {
    
    
		console.log('after mount', app.name);
		return Promise.resolve();
	}
});
  1. Call the start method to start the qiankun micro-frontend application:
start({
    
    
	sandbox: {
    
    
		experimentalStyleIsolation: false
	}
});
  1. In the root file of the main application, a sub-application container should be placed
<template>
  <div id="app">
    <Header />
    <div id="container">
      <Menu v-if="breadCrumbList.length" />
      <main :id="isSub.length ? 'main' : 'included'">
        <BreadCrumb v-if="breadCrumbList.length"/>
        <router-view :key="$route.path" ></router-view>
        <section id="commonContainer" v-if="!breadCrumbList.length"></section>
      </main>      
    </div>
  </div>
</template>

<script>
import Menu from "./layout/Menu.vue";
import Header from "./layout/Header.vue";
import BreadCrumb from "./layout/BreadCrumb";
export default {
    
    
  name: "App",
  components: {
    
    
    Menu,
    Header,
    BreadCrumb,
  },
  computed: {
    
    
    isSub() {
    
    
   	 // vue2写法写起来比较方便,就这样先举例了
      return this.$route.matched;
    },
  },
};
</script>

3. Configure qiankun in the sub-application

  1. install qiankun
  2. Configure in main.ts
// Element-plus
import ElementPlus from "element-plus";
import "element-plus/dist/index.css";
// Element Plus 组件 默认 使用英语
import zhCn from 'element-plus/es/locale/lang/zh-cn'
// Element-plus图标引入
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
// Echarts依赖引入
import * as echarts from 'echarts'
// 引入d3
import * as d3 from 'd3';
// 阿里字体
import "./assets/font/iconfont.css";
import './public-path';
import {
    
     createApp } from 'vue';
import {
    
     createRouter, createWebHistory } from 'vue-router';
import App from './App.vue';
import routes from './router';
import store from './store';
import {
    
     getLocationParams } from "@/utils/common.js"

// @ts-ignore
let router = null;
let instance = null;
let history = null;

// @ts-ignore
function render(props = {
    
    }) {
    
    
  // @ts-ignore
  const {
    
     container } = props;
  // @ts-ignore
  history = createWebHistory(window.__POWERED_BY_QIANKUN__ ? '/mainapp/subapp' : '/subapp');
 // history = createWebHistory();
  router = createRouter({
    
    
    history,
    // @ts-ignore
    routes,
  });
  // 由于登录页面是用的统一页面,所有登录逻辑放在了导航守卫里面
  router.beforeEach(async(to, from, next) => {
    
    
    const token = localStorage.getItem('token')
    if (token) {
    
    
    }else {
    
    
      if (getLocationParams("id_token")) {
    
    
        localStorage.setItem("token", getLocationParams("id_token"));
        await store.dispatch('getUserInfo')
        next()
      }else {
    
    
        store.dispatch('login')
      }
    }
    next()
  })
  instance = createApp(App);
  instance.use(router).use(store).use(ElementPlus, {
    
    locale: zhCn,});
  instance.mount(container ? container.querySelector('#apm') : '#apm');
  // 全局引入element-plus图标库
  for (const [key, component] of Object.entries(ElementPlusIconsVue){
    
    
    instance.component(key, component)
  }  
}
// 独立运行时:项目不在乾坤中调用则独立运行
// @ts-ignore
if (!window.__POWERED_BY_QIANKUN__) {
    
    
  render();
}
function storeTest(props) {
    
    
  props.onGlobalStateChange &&
    props.onGlobalStateChange(
      (value, prev) => console.log(`[onGlobalStateChange - ${
      
      props.name}]:`, value, prev),
      true,
    );
  props.setGlobalState &&
    props.setGlobalState({
    
    
      ignore: props.name,
      user: {
    
    
        name: props.name,
      },
    });
}
/**
 * bootstrap 只会在微应用初始化的时候调用一次,下次微应用重新进入时会直接调用 mount 钩子,不会再重复触发 bootstrap。
 * 通常我们可以在这里做一些全局变量的初始化,比如不会在 unmount 阶段被销毁的应用级别的缓存等。
 */
// @ts-ignore
export async function bootstrap() {
    
    
  console.log('%c%s', 'color: green;', 'vue3.0 app bootstraped');
}
// 应用每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法
export async function mount(props) {
    
    
  console.log('%c%s', 'color: green;',"子应用挂载")
  storeTest(props);
  render(props);
  instance.config.globalProperties.$onGlobalStateChange = props.onGlobalStateChange;
  instance.config.globalProperties.$setGlobalState = props.setGlobalState;
}
// 应用每次 切出/卸载 会调用的方法,通常在这里我们会卸载微应用的应用实例
export async function unmount() {
    
    
  console.log('%c%s', 'color: red;',"子应用卸载")
  instance.unmount();
  instance._container.innerHTML = '';
  instance = null;
  // 销毁路由,不然下次进入子应用时,不显示首页,而是展示上次定位的路由页面
  router = null;
  history.destroy();		
}
  1. Create a new public-path.ts under src
// 为了静态资源的引入
if (window.__POWERED_BY_QIANKUN__) {
    
    
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}

Uses of qiankun:

  • Micro front-end architecture : Multiple independent applications can be integrated into a whole, enabling multiple teams to develop in parallel, deploy and run independently, and improve development efficiency and flexibility.
  • Independent operation : Each independent front-end application can be developed and tested in its own development environment, and then deployed and run independently, which can avoid mutual influence and conflict between applications, and improve reliability and stability.
  • Shared resources : qiankun provides a resource sharing mechanism, which can manage public dependent libraries and resources in a unified way, avoiding repeated loading and waste. This reduces page load time and resource usage, improving performance and user experience.
  • Dynamic loading : qiankun supports dynamic loading of sub-applications, which can be loaded and unloaded as needed. This reduces initial load time and resource usage, and improves page responsiveness.
  • Cross-framework support : qiankun not only supports Vue.js, but also supports other mainstream front-end frameworks, such as React and Angular. This enables interoperability between different frameworks, increasing the flexibility and choice of the development team

Guess you like

Origin blog.csdn.net/bbt953/article/details/132378034