作者:京東物流 寧沖
1 前言
什么是微前端?
微前端是指存在于瀏覽器中的微服務,
本文主要通過對微前端框架single-spa的基座應用加載子應用的single-spa-vue函式庫進行分析,通過代碼維度分析讓大家了解在single-spa加載子應用的時候都做了哪些事情,如何通過優化single-spa-vue函式庫保持子應用的狀態,
由于是在代碼維度進行分析,要求讀者對single-spa有一定的了解,閱讀效果會更好,
2 single-spa加載子應用的程序
基座應用中配置的加載子應用配置,在配置子應用物件的app方法中會把子應用chunk-vendors.js、app.js插入到頁面,并且執行chunk-vendors.js、app.js兩個子應用依賴的js,

app方法執行結束以后,子應用依賴的js插入頁面以后的dom結構,

由上面app方法的執行程序,我們可以看出基座應用加載子應用,和vue框架打包后加載js資源的方式類似,那么為什么只需要加載子應用的app.js和chunk-vendors.js就可以把子應用渲染到頁面上面,下面我們再來看看子應用的入口檔案main.js方法中是如何進行配置的,
3 子應用的main.js中的配置
在子應用main.js中我們可以看到,把常規的配置1替換為配置2的格式,

在配置2中我們會把當前vue的配置傳給single-spa-vue函式庫中,包括el、render方法、Vue物件,通過singleSpaVue的包裝,回傳single-spa生命周期方法bootstrap、mount、unmount,
- bootstrap:引導函式,應用內容首次掛載到頁面前呼叫,只會執行一次,
- mount:掛載函式,子應用每次被掛載的時候都會執行,
- unmount:卸載函式,子應用每次被卸載的時候都會執行,
也就是說基座應用在加載子應用的時候就是通過single-spa-vue函式的處理,生成了single-spa的各個生命周期,給基座應用在加載子應用的時候呼叫,
下面我們來看看single-spa-vue究竟是如何生成各種生命周期函式的,
4 single-spa-vue原始碼結構
single-spa-vue函式庫可以幫助我們來生成加載子應用的生命周期,你可以通過下面鏈接:single-spa-vue GIT地址,下載single-spa-vue函式庫的原始碼,
single-spa-vue的原始碼非常簡單,只有幾個生成single-spa生命周期的函式,

- single-spa-vue方法:single-spa-vue函式庫對外提供服務的唯一一個方法,用來接收配置項,并且回傳一個包含各個single-spa生命周期的物件,
- single-spa-vue中的其他方法bootstrap、mount、update、unmount是用來生成single-spa對應生命周期函式的方法,
下面我們詳細介紹一下這幾個方法的作用和實作,
5 single-spa-vue原始碼決議
single-spa-vue中提供的singleSpaVue方法會接收userOpts配置資訊,配置資訊會和默認的配置項defaultOpts合并以后再進行進行后續處理,
5.1 配置項defaultOpts
對于默認的配置項會有下面這幾項,這里只介紹一下必填項,appOptions、Vue/createApp,其中的template在并沒有在single-spa-vue中被用到,但是在single-spa-html中有使用到,
-
// 默認配置項串列 -
const defaultOpts = { -
// required opts -
appOptions: null, -
template: null, -
// sometimes require opts -
Vue: null, -
createApp: null, -
handleInstance: null -
}
1)appOptions配置項介紹
- appOptions:應用的配置項,會在初始化Vue實體的時候作為引數傳給Vue方法,下面具體介紹一下appOptions中的配置項,
- el:子應用需要掛載的基座dom,即vue需要掛載的dom,
- render/template:vue的render/template配置項,
- data:初始化的引數物件,會在執行掛載函式mount的時候直接掛載到vue實體上,
2)Vue/createApp配置項介紹
Vue/createApp配置項是用來生成vue實體的,single-spa-vue函式庫可以通過傳入的Vue物件在mount方法中來生成vue實體,也可以傳入createApp方法,由子應用在createApp方法中回傳vue實體,
下面我們會在生命周期生成方法中看到這些配置項的作用
5.2 入口方法:singleSpaVue
singleSpaVue方法會對入參先進行下列有效性校驗,具體校驗的內容有一下四項,
- 配置項userOpts是否為物件,
- 用來創建vue實體的配置Vue/createApp是否存在,
- 用來生成vue實體的配置項appOptions是否存在,
- vue實體掛載的dom是否正確appOptions.el有效性校驗,

有效性校驗通過以后,會呼叫bootstrap、mount、unmount、update方法用來分別生成single-spa加載子應用的生命周期函式,
下面詳細介紹一下各個生命周期函式是如何生成的,
5.3 引導函式:bootstrap
引導函式bootstrap,當應用內容首次掛載到頁面前呼叫,

bootstrap函式,會先判斷一下是否在配置項中存在loadRootComponent,配置項loadRootComponent筆者理解是可以用來加載當前子應用依賴的父級應用或者其他的依萊澩,
比如A頁面依賴B組件,那在加載A頁面的時候可以loadRootComponent方法中把B組件的靜態資源加載下來,并且渲染到頁面上,A頁面就可以直接使用B組件中提供的一些資源或者dom,
如果未配置loadRootComponent,則直接回傳,不做任何處理,
5.4 子應用掛載生命周期:mount
在子應用每次被掛載到頁面上的時候,single-spa會執行mount生命周期函式,single-spa-vue在mount函式中用來初始化子應用的vue實體,并且把實體掛載到頁面上,
mount函式會接收三個引數,分別是singleSpaVue傳入的引數opts,single-spa-vue當前全域掛載的子應用實體串列mountedInstances,在基座應用中注冊的當前子應用的single-spa實體props
props入參接收的資料,這里只用到了props的name屬性,用來標識當前掛載的子應用,

在mount方法中主要做了以下幾件事
1)格式化應用配置項appOptions
mount方法中會通過resolveAppOptions方法來格式化應用的配置項appOptions,
在resolveAppOptions方法來中如果appOptions是一個方法的話,則執行方法,并且傳遞基座應用通過customProps引數傳入的引數props,
子應用可以在appOptions方法中獲取父應用傳遞的引數、根據父應用的狀態做不同的處理等,

2)初始化子應用需要掛載的DOM物件,
初始化dom的配置和方法比較多,會從很多個配置項中來獲取el,代碼比較簡單,這里就不贅述了,只列出來取值的優先級供大家參考,
appOptions.el > props.domElement > props.name

dom節點被格式化完成以后,下面就開始把頁面掛載到dom上面,
3)創建vue示例,并且掛載到頁面上
在掛載頁面之前會有一個配置項:replaceMode,replaceMode配置項是用來標識是否需要替換el節點下的內容,默認replaceMode為false是會在el節點下面新建一個class為single-spa-container的空白div來保存子應用,
以demo中的代碼為例:

默認replaceMode為false的情況下,基座中的的內容和vue1中的內容會并存,如下圖:

如果把replaceMode改為true的情況下,會發現基座中的內容會被vue1中的內容覆寫掉,
如下圖:

設定掛載方式以后,就開始把子應用真正掛載到dom上面,
這里支持兩種掛載方式,一種是使用vue3的createApp方式掛載,一種是使用vue2的new Vue方式進行掛載,這里的掛載方式其實和我們在使用vue掛載到dom方式的配置是一樣的,

通過上面的步驟,此時子應用就被掛載到了html的頁面中的dom上了,
5.5 更新生命周期函式:update
當呼叫parcel.update()會觸發update方法,筆者由于并沒有用的高級特性parcel,在此處不再做過多介紹,
5.6 子應用卸載生命周期:unmount
當頁面url發生變化的時候,離開子應用頁面路由的時候會觸發unmount方法,
在unmount方法中主要做的事情有:
- 卸載vue應用
- 洗掉vue實體
- 同時清空頁面dom,

執行unmount操作以后子應用的資料和dom就會被清除干凈,
5.7 小結
以上就是single-spa官方提供的single-spa-vue函式庫來掛載子應用的全部流程,通過上面的分析,我們發現single-spa-vue函式庫會通過呼叫singleSpaVue方法回傳一個包含bootstrap、mount、update、unmount四個方法的物件,在基座應用加載子應用的生命周期會執行對應的方法,通過執行方法把子應用掛載到基座應用或者從基座應用銷毀子應用,
通過single-spa-vue中加載子應用的程序,single-spa把各個子應用組裝成一個復雜的應用,在用戶無感的情況下對各個子應用進行分別治理,
single-spa在加載子應用的時候,除了vue的版本之外,還有其他的版本,但是加載的思路類似,都是在函式庫中來把子應用加載到html中,此處不再介紹其他型別的加載,
single-spa其他加載子應用方式:single-spa-react、single-spa-html
6 子應用狀態保持
在實際開發的程序中筆者遇到有些頁面需要使用vue中的keep-alive來保留狀態,在頁面切換的程序中雖然頁面被銷毀但是頁面狀態需要在保留,但是我們在分析single-spa-vue的unmount方法實作的時候發現,如果頁面切換,子應用和vue實體被銷毀,此時子應用中的keep-alive是沒有生效的,
如下圖:

當在input中輸入內容以后,傳統的spa專案可以通過keep-alive來記錄狀態,當頁面路由切換以后,再切回來,仍然保持狀態,但是如果直接使用single-spa-vue,當子應用觸發unmount的時候input中的輸入內容1111會被清空,針對這種情況,筆者對single-spa-vue類別庫進行了一些改造,
改造內容如下:
6.1 子應用由銷毀改為隱藏
在single-spa-vue配置項中增加了一個配置項,根據配置項中是否存在isKeepAlive配置項,來判斷把當前的dom隱藏掉,還是洗掉,這樣當子應用unmount方法觸發的時候,子應用并未被洗掉,而是仍然保留,

同時筆者對vue的route配置也進行了一些優化,當頁面不存在的時候,此時會把子應用中的一個空組件掛載到dom上面,避免雖然頁面被隱藏掉,但是dom仍然在html中,導致頁面dom過多,

6.2 子應用由新建改為顯示
在single-spa-vue配置項中呼叫mount方法掛載子應用的時候,會判斷當前子應用是否存在,如果子應用存在則直接把子頁面顯示出來,由于子應用并未被銷毀,此時子應用中的keep-alive就會一直生效,并且保存頁面的狀態,

通過對single-spa-vue類別庫的mount、unmount方法的優化,用戶在使用頁面的時候真正和使用vue那樣流暢,并且可以保持頁面狀態,提升用戶的體驗,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/548516.html
標籤:其他
上一篇:三分鐘速覽GPT系列原理
