参考:
官网: https://qiankun.umijs.org/zh/guide
介绍
微前端
微前端是一种多个团队通过独立发布功能的方式来共同构建现代化 web 应用的技术手段及方法策略。
微前端架构具备以下几个核心价值:
技术栈无关
主框架不限制接入应用的技术栈,微应用具备完全自主权。
独立开发、独立部署
ps: 但是乾坤还是有侵入性,需要在微应用添加对应的生命周期。
微应用仓库独立,前后端可独立开发,部署完成后主框架自动完成同步更新。
增量升级
在面对各种复杂场景时,我们通常很难对一个已经存在的系统做全量的技术栈升级或重构,而微前端是一种非常好的实施渐进式重构的手段和策略。
独立运行时
每个微应用之间状态隔离,运行时状态不共享。
摘自乾坤官网
乾坤(qiankun)
qiankun 是一个基于 single-spa 的微前端实现库,旨在帮助大家能更简单、无痛的构建一个生产可用微前端架构系统。
实践
应用分为主应用和微应用,主应用需要安装qiankun的包,而微应用不需要。
主应用
1.安装qiankun
$ yarn add qiankun # 或者 npm i qiankun -S
2.在主应用中注册微应用
import { registerMicroApps, start } from 'qiankun';
registerMicroApps([
{
name: 'react app', // app name registered
entry: '//localhost:7100',
container: '#yourContainer',
activeRule: '/yourActiveRule',
},
{
name: 'vue app',
entry: { scripts: ['//localhost:7100/main.js'] },
container: '#yourContainer2',
activeRule: '/yourActiveRule2',
},
]);
start();
当微应用信息注册完之后,一旦浏览器的 url 发生变化,便会自动触发 qiankun 的匹配逻辑,所有 activeRule 规则匹配上的微应用就会被插入到指定的 container 中,同时依次调用微应用暴露出的生命周期钩子。
实践中我们需要将微应用的跳转关联到路由中以达到基本使用,所以对上面的情况进行如下修改(以官网Vue示例):
在Vue的main.ts中注册微应用
import './assets/main.css'
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import { registerMicroApps } from 'qiankun'
import App from './App.vue'
import router from './router'
const app = createApp(App)
app.use(createPinia())
app.use(router)
registerMicroApps([
{
name: 'app-vue-qk',
entry: '//localhost:8090', // 独立
// entry: '/app-vue/', // 整合
container: '#child',
activeRule: '/app-vue-qk',
props: {
routers: router,
}
}
]);
app.mount('#app')
创建一个qiankun.vue的页面
<template>
<div id="child" class="about"></div>
</template>
<script setup lang="ts">
import { onMounted } from 'vue'
import { start } from 'qiankun'
onMounted(() => {
// 启动 qiankun
start({
sandbox: {
experimentalStyleIsolation: true // 样式隔离
}
})
})
</script>
在vue-router路由中添加
{
path: "/app-vue-qk/:abc*",
name: 'app-vue-qk',
component: () => import("../views/qiankun.vue")
}
ps: 注意在不同版本的vue-router中写法会有所不同!
以上我们完成了主应用的初始化。
微应用
微应用官方示例为vue2,这里我们也使用vue2,微应用不需要额外安装任何其他依赖即可接入 qiankun 主应用。
1.在 src 目录新增 public-path.js
if (window.__POWERED_BY_QIANKUN__) {
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
2.入口文件 main.js 修改
为了避免根 id #app 与其他的 DOM 冲突,需要限制查找范围。
import './public-path';
import Vue from 'vue';
import VueRouter from 'vue-router';
import App from './app.vue';
import routes from './router';
import './css/base.css'
Vue.use(VueRouter);
Vue.config.productionTip = false;
let router = null;
let instance = null;
function render(props = {}) {
const { container } = props;
router = new VueRouter({
base: window.__POWERED_BY_QIANKUN__ ? '/app-vue-qk/' : '/',
mode: 'history',
routes: routes.routes,
});
instance = new Vue({
router,
render: (h) => h(App),
}).$mount(container ? container.querySelector('#app') : '#app');
}
// 独立运行时
if (!window.__POWERED_BY_QIANKUN__) {
render();
}
export async function bootstrap() {
console.log('[vue] vue app bootstraped');
}
export async function mount(props) {
console.log('[vue] props from main framework', props);
render(props);
}
export async function unmount() {
instance.$destroy();
instance.$el.innerHTML = '';
instance = null;
router = null;
}
3.打包配置修改(vue.config.js)
const name = "app-vue-qk";
module.exports = {
devServer: {
headers: {
'Access-Control-Allow-Origin': '*', // 运行时允许跨域
},
},
configureWebpack: {
output: {
library: `${name}-[name]`,
libraryTarget: 'umd', // 把微应用打包成 umd 库格式
jsonpFunction: `webpackJsonp_${name}`, // webpack 5 需要把 jsonpFunction 替换成 chunkLoadingGlobal
},
},
};
以上配置好微应用后即可启动主应用和微应用进行验证。
ps:实践案例 https://github.com/sunshihao/qiankunDemo
部署方式
主要分为同服务器部署和非服务器部署详情可见官网说明。
总结
乾坤实践后达到了基本应用,一些细节的设置在官网上没有明确的说明,耗费了一些时间。
TODO
微应用跳转微应用
微应用跳转主应用
相应的自动化部署发布