qiankun + Vue实现微前端服务
本文介绍如何使用qiankun
+ Vue
搭建一个前端微服务
一、什么是微前端
Techniques, strategies and recipes for building a modern web app with multiple teams that can ship features independently. -- Micro Frontends
微前端是一种多个团队通过独立发布功能的方式来共同构建现代化 web 应用的技术手段及方法策略。
以上内容均来自于 qiankun手册,有兴趣可以也看看这个api文档,很多关于微前端的困惑都在里面,以及为什么是不用iframe
等....
本文代码,可以直接食用:qiankun-demo
效果:
二、创建应用
在本例子中,我们需要通过vue-cli
创建创建一个主应用,两个子应用。
目录结构:
|——qiankun-demo // 主文件夹
|——|——child-app01 //子应用1
|——|——child-app02 //子应用2
|——|——main-app //主应用
|——|——server.js // 自己写的一个快捷启动服务脚本,手动启动服务的可以忽略
|——|——package.js // 脚本依赖,手动启动服务的可以忽略
三、应用配置
主应用相关代码:
qiankun
是通过registerMicroApps(apps, lifeCycles)
API来注册子应用的,在main-app目录下
npm install qiankun -S
npm install element-ui -S // 引入element快速实现样式
main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import element from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(element);
import { registerMicroApps, start } from 'qiankun'
Vue.config.productionTip = false
const microAppNum = 2
let apps = [];
for (let i = 1; i <= microAppNum; i++) {
apps.push(
{
name: '子应用child0' + i,
entry: 'http://localhost:90' + i + '0',
//fetch,
container: '#vue',
activeRule: '/child0' + i,
props: { param01: i }
}
);
}
const config = {
beforeLoad: [
app => {
console.log("%c before load",
'background:#0f0 ; padding: 1px; border-radius: 3px; color: #fff',
app);
}
], // 挂载前回调
beforeMount: [
app => {
console.log("%c before mount",
'background:#f1f ; padding: 1px; border-radius: 3px; color: #fff',
app);
}
], // 挂载后回调
afterUnmount: [
app => {
console.log("%c after unload",
'background:#a7a ; padding: 1px; border-radius: 3px; color: #fff',
app);
}
] // 卸载后回调
}
registerMicroApps(apps, config);
let option = { prefetch: false }
start();
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
- 如果暂时不需要看到生命周期的输出,可以不定义
config
,同时注册应该时registerMicroApps(apps, config);
把里面的config
去掉即可 - 其中的
container
内的#vue
,对应app.vue内的id="vue"
元素块
vue.config.js
若不存在该文件,新建一个vue.config.js
module.exports = {
devServer: {
port: 9000,
headers: {
//'Access-Control-Allow-Origin': "*"
}
}
};
App.vue
利用引入的element,快速搭建一个简单的页面
<template>
<div>
<el-menu :router="true" mode="horizontal">
<el-menu-item index="/">首页</el-menu-item>
<el-menu-item v-for="no in microAppNum" :key="no" :index="'/child0'+no">子应用0{{no}}</el-menu-item>
</el-menu>
<router-view />
<!-- 子应用入口 -->
<div id="vue"></div>
</div>
</template>
<script>
export default {
name: "main01",
data() {
return {
microAppNum: 2
};
},
};
</script>
子应用配置
mian.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
// Vue.config.productionTip = false
let install = null;
function render(props) {
install = new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
}
if (window.__POWERED_BY_QIANKUN__) {
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
} else {
render();
}
export async function bootstrap(props) {
}
export async function mount(props) {
render(props);
}
export async function unmount(props) {
install.$destroy();
}
vue.config.js
同样,在该文件内,
const port = 9010; // 一个应用写9010,另一个写9020
module.exports = {
devServer: {
port,
headers: {
'Access-Control-Allow-Origin': '*'
}
},
configureWebpack: {
output: {
library: 'child',
libraryTarget: 'umd'
}
}
};
子应用必须支持跨域:由于
qiankun
是通过fetch
去获取子应用的引入的静态资源的,所以必须要求这些静态资源支持跨域;
本地服务直接在vue.config.js
内配上跨域相关即可,上线的话,需要在服务器配置白名单。后续文章将更新跟打包相关内容。
/router/index.js
这里需要特别注意,我们在父应用注册微服务的时候,写了相关activeRule,
所以子应用路由这边配置也要相应的修改
image.png
四、使用
分别进入父子应用目录
npm run serve
全部启动后,可以单独打开子应用,看到页面,也可以在主应用内,直接看到里面的子应用,效果类似iframe。
发现服务启动,因为代码端口写死,若端口冲突,可以关闭端口重新启动服务,或者修改代码。
由于我不想每次都进入父子应用目录,去重复启动多个服务,手动写了一个node脚本,去快速启动三个服务,可以手动启动服务的,可忽略该脚本,分别手动启动三个服务即可。