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
效果:

微前端效果.gif

二、創建應用

在本例子中,我們需要通過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腳本,去快速啟動三個服務,可以手動啟動服務的,可忽略該腳本,分別手動啟動三個服務即可。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。