微前端——使用qiankun構建多技術棧微前端架構


前言

隨著微服務的興起,後端在這一方面有了很好的解決方案。前端目前流行的就是使用qiankun去構建微前端架構。

什麼是qiankun

Qiankun:基於Single-Spa,阿里系開源微前端框架。具有以下特點:

簡單——任意js 框架均可使用。微應用接入像使用接入一個 iframe 系統一樣簡單,但實際不是 iframe

完備——幾乎包含所有構建微前端系統時所需要的基本能力,如 樣式隔離js 沙箱預加載等。

生產可用——已在螞蟻內外經受過足夠大量的線上系統的考驗及打磨,健壯性值得信賴。

構建基礎應用

今天我們將會使用Vue項目作為基座,來聯合Vue和React的兩個子應用來構建一個微前端架構體系。為方便大家理解,下面我整理了架構圖:

需要構建的三個應用分別是Vue主應用(qk-base)Vue子應用(qk-vue)React子應用(qk-react)

// Vue主應用(基座)vue create qk-base// Vue子應用vue create qk-vue// react子應用npx create react-app qk-react

創建完成後文件夾中就會有以下三個項目:

主應用(基座)配置

菜單和樣式配置

為更方便展示應用的切換我們對主應用的首頁進行配置,使用element-ui的菜單對其進行優化展示。使其可以通過切換來顯示不同的應用信息。

安裝elementUi

npm i element-ui -S// main.jsimport ElementUI from 'element-ui';import 'element-ui/lib/theme-chalk/index.css';Vue.use(ElementUI);

App.vue

  主應用頁面  Vue應用  react應用            

在這裡,我們設定Vue子引用的路徑開頭為‘/vue’,React子應用的開頭為‘/react’。並使用id=”vue”id=”react”兩個div來接收他們。

值得一提的是,主應用的路由也可以通過router-view來進行路由切換。

主應用qiankun配置

安裝qiankun

yarn add qiankun # 或者 npm i qiankun -S

引入qiankun

main.js

import { registerMicroApps, start } from 'qiankun';// ...let apps = [  {    name: 'vue faxian', // 子應用名稱    entry: '//localhost:10000', // 默認會加載這個html解析裡面的js動態的執行,因為請求了資源子應用需要支持跨域    container: '#vue', // 掛在到那個節點上    activeRule: '/vue', // 訪問某個URL的時候將這個埠號掛在到這個上去  },  {    name: 'react exam',     entry: '//localhost:20000',    container: '#react',    activeRule: '/react',  },];registerMicroApps(apps); // 註冊應用start({  prefetch: false // 取消預加載 }); // 開啟

我們分別使用 1000020000埠去分別監聽Vue和React兩個子應用。

子應用Vue配置

在子應用中必須要三個函數(必須是promise的):bootstrap()mount()unmount()。我們這裡使用async函數將其導出。

main.js

// 子組件協議/** * 啟動時 * */export async function bootstrap(){}/** * 創建時 * @param {*} props 父應用傳過來的數據 */export async function mount(props){  render(props)}/** * 卸載時 */export async function unmount(){  instance.$destroy();  instance.$el.innerHTML = "";  instance = null;}

我們需要更新子應用路由的一些配置,包括設置根目錄和調為history模式:

router/index.js

// your router config ...const router = new VueRouter({    mode: 'history', // 設置路由模式為history    base:'/vue', // 設置根目錄為 /vue    routes})export default router;

設置創建vue實例的方法 render(),這裡是掛載到自己的html中,基座會拿到這個掛載後的html將其插入進去。

main.js

function render(){  instance = new Vue({    router,    // store // 也可以傳遞父應用的vuex    render: h => h(App),  }).$mount('#app') // 這裡是掛載到自己的html中,.基座會拿到這個掛載後的html將其插入進去}

當然我們需要獨立運行時也能正常運行,qiankun提供一個參數__POWERED_BY_QIANKUN__來判斷是不是在獨立運行:

main.js

// 使用 webpack 運行時 publicPath 配置if(window.__POWERED_BY_QIANKUN__){ // 動態添加public_path  // eslint-disable-next-line no-undef  __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;}// 獨立運行微應用if (!window.__POWERED_BY_QIANKUN__) { // 默認獨立運行  render();}

最後我們配置上打包就可以了。

vue.config.js

module.exports = {    devServer:{        port:10000, // 啟用10000埠來監聽        headers:{            'Access-Control-Allow-origin':'*' // 配置本地運行時允許跨域        }    },    configureWebpack:{        output:{            library: 'vueApp',             libraryTarget: 'umd'        }    }}

運行後的結果:

子應用React配置

想要配置React項目,我們首先要重寫配置文件。這邊我們藉助react-app-rewired將我們的React配置進行變線(注意是把線路改變不是變現)。

yarn add react-app-rewired

更改我們的啟動項,將原來的react-scripts改為react-app-rewired

package.json

"scripts": {    "start": "react-app-rewired start",    "build": "react-app-rewired build",    "test": "react-app-rewired test",    "eject": "react-app-rewired eject"  }

在根目錄中建立配置文件config-overrides.js

config-overrides.js

module.exports = {    webpack:(config)=> {        config.output.library = 'reactApp'; // 打包的類庫,項目名稱        config.output.libraryTarget = 'umd';         config.output.publicPath = 'http://localhost:20000/'; // 埠        return config;    },    devServer:(configFunction)=>{        return function(proxy,allowedHost){            const config = configFunction(proxy,allowedHost);            config.headers = {                'Access-Control-Allow-origin':'*' // 配置都允許跨域            }            return config;        }    }}

建立配置文件.env配置完成埠號

.env

PORT = 20000WDS_SOCKET_PORT= 20000

和上面的項目一樣我們需要導出固定名稱的三個方法:bootstrap()mount()unmount()

src/index.js

// 子組件協議/** * 啟動時 * */ export async function bootstrap(){} /**  * 創建時  * @param {*} props   */ export async function mount(props){   render(props) } /**  * 卸載時  * @param {*} props   */ export async function unmount(){  ReactDOM.unmountComponentAtNode(document.getElementById('root')); }

封裝一個render(),本地運行時候進行判斷,使其可以獨立運行。

src/index.js

function render(){  ReactDOM.render(              ,    document.getElementById('root')  );}// 獨立運行微應用if (!window.__POWERED_BY_QIANKUN__) { // 默認獨立運行  render();}

然後我們配置ReactRouter

安裝router

yarn add react-router-dom

這邊簡單的配置router和頁面

function App() {  return (          首頁      關於頁面       
首頁
}>
關於頁面
}>
);}export default App;

yarn start 後就發現開始運行讀取我們自己的配置文件了

最終效果:

數據通信

比方說我們現在需要將主應用的用戶信息同步到子應用中。

我們可以通過配置主應用的main.js來傳遞參數,當然這裡可以以是vuex或者redux

在子應用的mount方法中去接收這個參數

qk-vue main.js

export async function mount(props){  if(props?.userInfo){    console.log(props.userInfo)    // 設置主應用過來的參數    window.sessionStorage.setItem('userInfo',props.userInfo);  }  render(props)}

推薦文章  買年貨,省錢看這裡,京東淘寶年貨節開搶
Scroll to Top