qiankun基础与应用
概念
qiankun是蚂蚁金融科技基于 single-spa 的微前端实现库. 提供了更加开箱即用的API, 接入简单(类似于iframe一样简单)并且实现了css样式隔离与js沙箱机制.
运行时动态加载, 主子应用完全结偶, 采用协议API接入(子应用必须导出 bootstrap, mount, unmount方法)
TIP
qiankun 只确保子应用之间样式隔离,主应用跟子应用之间的样式冲突需要手动解决,主应用可以通过设置 prefixCls 的方式避免冲突. 参考issue
实现思路(同single-spa)
将一个应用划分成若干个子应用, 将子应用打包成一个个的lib, 当路径切换时加载不同的子应用, 这样子应用都是独立的, 技术栈也不用做限制了, 解决了前端协调开发问题
使用流程
主应用(Vue)
yarn add qiankun
js
// main.js
import { registerMicroApps, start } from 'qiankun'
// 子应用配置
let apps = [
{
name: 'vue-project1', // 名称
entry: '//localhost:8081', // 入口 【也可以使用/path 再nginx路由转发】
container: '#vue-project1', // 挂载自应用的容器(此id在父元素中定义)
activeRule: '/vue-project1', // 激活的路由规则【给single-spa使用】
props: {
msg: `hellow, vue-project1, I'm your father.` // 传递给子应用的props,子应用通过三个协议API可获取
}
},
{
name: 'vue-project2',
entry: '//localhost:8082',
container: '#vue-project2',
activeRule: '/vue-project2',
props: {
msg: `hellow, vue-project2, I'm your father.`
}
},
{
name: 'vue-project3',
entry: '//localhost:8083',
container: '#vue-project3',
activeRule: '/vue-project3',
props: {
msg: `hellow, vue-project3, I'm your father.`
}
}
]
// 注册子应用, 可以配置生命周期:https://qiankun.umijs.org/zh/api#registermicroappsapps-lifecycles
registerMicroApps(apps, {
beforeLoad: (app) => console.log('beforeLoad: ', app.name)
})
// 启动&配置:https://qiankun.umijs.org/zh/api#startopts
start({
// prefetch: true
})
子应用
在入口文件暴露三个qiankun协议的API函数
main.js配置
js
// main.js
let instance = null
function render(props) {
Vue.config.productionTip = false
instance = new Vue({
router,
render: function (h) {
return h(App)
}
}).$mount('#app') // 【不能与基座应用冲突!】挂载到自己的容器中. 基座应用会获取整个html插入
}
// 判断是否作为【独立应用】渲染 https://qiankun.umijs.org/zh/faq#%E5%A6%82%E4%BD%95%E7%8B%AC%E7%AB%8B%E8%BF%90%E8%A1%8C%E5%BE%AE%E5%BA%94%E7%94%A8%EF%BC%9F
if (!window.__POWERED_BY_QIANKUN__) {
render()
} else {
// 作为子应用时,需要动态配置webpack的publicPath,以获取static文件
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
// 乾坤子应用协议必须导出的三个API
// props可用于主-子应用通信
export async function bootstrap(props) {} // 启动
// 挂载
export async function mount(props) {
console.log('vue-project1接收到props:', props)
render(props)
}
// 卸载
export async function unmount(props) {
instance.$destroy()
}
路由判断
js
// router/index.js
const router = new VueRouter({
mode: 'history',
base: window.__POWERED_BY_QIANKUN__ ? '/vue-project1' : './',
routes
})
打包成lib&允许跨域配置
js
// vue.config.js
module.exports = {
devServer: {
host: 'localhost',
port: '8081',
// 配置应用可被get请求跨域访问
headers:{
'Access-Control-Allow-Origin': '*'
}
},
// 配置打包成lib库
configureWebpack: {
output: {
library: 'vue-project1', // 包名称
libraryTarget: 'umd', // 包规范
jsonpFunction: 'webpackJsonp_child-app-name' // 防止渲染冲突
}
}
}
TIP
jsonpFunction
:webpack默认将懒加载的模块存储在webpackJsonp
的数组中。当多个项目使用webpack构建,都会push在这一个数组中,假如webpack
需要执行入口模块(chunk-vendors
),则会执行多个chunk-vendors
, 造成渲染冲突.【不过有js沙箱隔离,貌似不配置这个也没啥问题】 webpack文档