本文介紹如何使用qiankun
+ Vue
搭建一個前端微服務
一尝艘、什么是微前端
Techniques, strategies and recipes for building a modern web app with multiple teams that can ship features independently. -- Micro Frontends
微前端是一種多個團隊通過獨立發(fā)布功能的方式來共同構(gòu)建現(xiàn)代化 web 應用的技術(shù)手段及方法策略妖枚。
以上內(nèi)容均來自于 qiankun手冊楞件,有興趣可以也看看這個api文檔塘揣,很多關于微前端的困惑都在里面,以及為什么是不用iframe
等....
本文代碼,可以直接食用:qiankun-demo
效果:
二、創(chuàng)建應用
在本例子中劣光,我們需要通過vue-cli
創(chuàng)建創(chuàng)建一個主應用,兩個子應用糟把。
目錄結(jié)構(gòu):
|——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快速實現(xiàn)樣式
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);
}
], // 掛載前回調(diào)
beforeMount: [
app => {
console.log("%c before mount",
'background:#f1f ; padding: 1px; border-radius: 3px; color: #fff',
app);
}
], // 掛載后回調(diào)
afterUnmount: [
app => {
console.log("%c after unload",
'background:#a7a ; padding: 1px; border-radius: 3px; color: #fff',
app);
}
] // 卸載后回調(diào)
}
registerMicroApps(apps, config);
let option = { prefetch: false }
start();
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
- 如果暫時不需要看到生命周期的輸出,可以不定義
config
缠犀,同時注冊應該時registerMicroApps(apps, config);
把里面的config
去掉即可 - 其中的
container
內(nèi)的#vue
数苫,對應app.vue內(nèi)的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
同樣文判,在該文件內(nèi),
const port = 9010; // 一個應用寫9010室梅,另一個寫9020
module.exports = {
devServer: {
port,
headers: {
'Access-Control-Allow-Origin': '*'
}
},
configureWebpack: {
output: {
library: 'child',
libraryTarget: 'umd'
}
}
};
子應用必須支持跨域:由于
qiankun
是通過fetch
去獲取子應用的引入的靜態(tài)資源的戏仓,所以必須要求這些靜態(tài)資源支持跨域;
本地服務直接在vue.config.js
內(nèi)配上跨域相關即可亡鼠,上線的話赏殃,需要在服務器配置白名單。后續(xù)文章將更新跟打包相關內(nèi)容间涵。
/router/index.js
這里需要特別注意仁热,我們在父應用注冊微服務的時候,寫了相關activeRule勾哩,
所以子應用路由這邊配置也要相應的修改
四抗蠢、使用
分別進入父子應用目錄
npm run serve
全部啟動后举哟,可以單獨打開子應用,看到頁面迅矛,也可以在主應用內(nèi)妨猩,直接看到里面的子應用,效果類似iframe秽褒。
發(fā)現(xiàn)服務啟動壶硅,因為代碼端口寫死,若端口沖突销斟,可以關閉端口重新啟動服務庐椒,或者修改代碼。
由于我不想每次都進入父子應用目錄蚂踊,去重復啟動多個服務约谈,手動寫了一個node腳本,去快速啟動三個服務犁钟,可以手動啟動服務的窗宇,可忽略該腳本,分別手動啟動三個服務即可特纤。