微前端是將Web應用由單一的單體應用轉(zhuǎn)變?yōu)槎鄠€小型前端應用聚合為一的一種手段。本文從微前端的基礎理論出發(fā),與大家分享長亮科技Web 前端團隊的探索與實踐經(jīng)驗。
作者
Yang.Q 前端架構(gòu)師
擁有10年前端開發(fā)和從業(yè)經(jīng)驗,負責前端生態(tài)建設以及低代碼、微前端等前端前沿技術(shù)的探索工作。
數(shù)字時代,隨著技術(shù)的不斷變革,前后端分離架構(gòu)的研發(fā)模式已成為主流。但爆發(fā)式增長的業(yè)務量讓前端功能需求不斷增多,小而美的應用不復存在。當一個普通應用演變成一個巨石應用( Frontend Monolith )后,邏輯復雜和臃腫的問題開始暴露,隨之而來的是多人難以協(xié)作、功能耦合性高、頁面加載速度變慢等一系列難題亟待解決。
當后端「微服務」廣泛普及時,「微」的概念也影響到了前端,「微前端」應運而生。
微前端(Micro-Frontends)是一種類似于微服務的架構(gòu),它將微服務的理念應用于瀏覽器端,即將 Web 應用由單一的單體應用轉(zhuǎn)變?yōu)槎鄠€小型前端應用聚合為一的應用,各個前端應用可以獨立運行、獨立開發(fā)、獨立部署。
通過跟微服務進行對比,我們可以更清晰地理解微前端的概念:


相比于傳統(tǒng)的前端工程,微前端架構(gòu)具備以下幾大優(yōu)勢:
大幅提升研發(fā)效能:將大工程進行拆分,顯著提高打包構(gòu)建速度,代碼簡潔、解耦、更易維護;
定制化編排產(chǎn)品:將微應用進行個性化編排組合,快速進行產(chǎn)品創(chuàng)新;
定向增量升級:各微前端單獨部署,可定向增量升級某一微應用,而不影響其他微應用,大大節(jié)省了部署成本和降低升級風險。
基于豐富的技術(shù)實踐經(jīng)驗,長亮科技Web前端團隊在微前端領(lǐng)域的深入探索已有所建樹。本文將重點分享在微服務框架的背景下,長亮科技自主研發(fā)和設計的微前端解決方案。
微前端技術(shù)選型之路
微前端架構(gòu)的實現(xiàn)方式有多種技術(shù)路線,包括路由分發(fā)式、應用微服務化、微應用、微件化、前端容器化、應用組件化等,需根據(jù)具體場景選用合適的方式。在某些場景下,可能沒有合適的方案,也可能同時使用多種方案。
因此在做技術(shù)選型前,首先需要對公司的產(chǎn)品現(xiàn)狀進行整體梳理,結(jié)果如下:
現(xiàn)有前端框架:公司主流使用vue,但是一些老舊系統(tǒng)仍使用react、jquery等;
前端工程拆分粒度:大部分產(chǎn)品還是傳統(tǒng)的大工程形態(tài);有部分產(chǎn)品已進行了模塊化、組件化拆分,將一個大工程拆分成了多個小工程,各工程通過發(fā)布npm插件的形式,最終被一個主工程安裝聚合。
通過對公司現(xiàn)有產(chǎn)品的分析,最終我們最終確認了技術(shù)選型的要求:
能夠做到跨技術(shù)棧,不局限于一種前端框架;
能夠?qū)pm插件改造成以微應用的形式進行聚合。
此外,根據(jù)我們的產(chǎn)品特性,微前端框架還需滿足以下幾點需求:
● 微應用獨立開發(fā)
● 微應用獨立部署
● 跨技術(shù)棧,不局限于一種前端框架
● 能夠?qū)pm插件改造成以微應用的形式進行聚合
● 可將微應用進行編排組合,輸出不同的產(chǎn)品
● 加載器底座使用vue
結(jié)合公司的框架能力需求,我們最終選定三種微前端技術(shù)路線結(jié)合的方式:
應用微服務化:針對于無法拆分的系統(tǒng)和非vue系統(tǒng),采取微服務化接入,進行技術(shù)驗證后選擇了阿里qiankun框架;
微應用化:針對vue技術(shù)棧已做模塊化拆分的系統(tǒng)工程,采取微應用化接入,使用了webpack5提供的模塊聯(lián)邦;
前端容器化: 針對一些老舊的非spa單頁面的系統(tǒng),采取iframe接入。
微前端解決方案設計思路
從前文所述的微前端概念可知,中心加載器是微前端的核心所在,而加載器需具備三個基本能力:
路由分發(fā);
加載微應用的靜態(tài)資源;
可在加載器上任意上架下架微應用。
基于上述認知,我們對微前端解決方案的各個模塊做了如下設計:
標識微應用
如何保證加載器能正確的識別到對應的微應用呢?
我們決定為每一個微應用定制一個唯一id標記,即編碼appCode。
中心化路由
微服務的核心是注冊中心,微前端是否也需要一個注冊中心呢?如果需要,那么微前端的注冊中心又是什么呢?
通常情況下,前端頁面的渲染是靠路由來控制的,那我們是否可以利用前端的路由體系來設計一套微前端的注冊中心呢?
基于這個思路,我們初步設計了一套加載器的工作流程:

1) 加載器底座拉取微應用配置信息
2) 將配置中的微應用注冊到注冊中心
3) 瀏覽器url變更驅(qū)動loader加載器加載對應微應用的資源
4) 加載微應用
微應用配置
依據(jù)上述加載器的工作流程圖,我們整理出微應用的配置文件結(jié)構(gòu)以及字段:

注冊中心
依據(jù)上文提到的注冊中心即是路由的思路,構(gòu)建出如下路由結(jié)構(gòu)(以vue-router為例):

以微應用唯一編碼做為路由的name[path]。
這里需要注意的是,考慮到微應用的動態(tài)加載,加載器加載的微應用個數(shù)不做限制,如一次性將所有的微應用路由全部加載,勢必會造成路由數(shù)據(jù)過于龐大,因此初始化時只注冊中心路由,微應用對應的頁面路由,則在第一次進入當前微應用的時候創(chuàng)建。此步驟放在loader加載器中實現(xiàn)。
Loader加載器
加載器通過監(jiān)聽路由切換,主動獲取路由對應的微應用的靜態(tài)資源,繼而進行頁面渲染。
加載器主要工作流程如下:

依據(jù)此流程可以編寫出加載器的流程代碼(以vue為例):
微應用設計
微應用的設計分為微服務化接入(qiankun)和微應用化接入。
1、微服務化-qiankun
首先在應用入口增加qiankun的生命周期
為了讓微應用能被加載器順利加載,其構(gòu)建后的文件結(jié)構(gòu)以及構(gòu)建路徑需做適配。
為了區(qū)分請求資源的歸屬,在每個靜態(tài)資源前都加上了appCode(微應用編碼),例如/app1/index.index,/app1/lib.js ,/app1/lib.css。因此在構(gòu)建時候publicPath需設置成”./”相對路徑。
構(gòu)建后的文件夾一級目錄下需包含微應用的配置文件和入口文件。
以下為qiankun應用打包后的文件結(jié)構(gòu):
config.json:微應用配置文件
Index.html:微應用入口文件
2、微應用化-模塊聯(lián)邦
模塊聯(lián)邦主要是利用wenpack5提供的ModuleFederationPlugin將組件模塊化輸出。
通過模塊聯(lián)邦導出組件,最終生成的文件結(jié)構(gòu)如下:
config.json:微應用配置文件
remoteEntry.js:微應用入口文件
長亮科技微前端框架產(chǎn)品
綜上所述方案設計整體思路,經(jīng)過產(chǎn)品化打磨后,長亮科技Web前端團隊基于公司現(xiàn)有前端低代碼平臺,自主研發(fā)和設計的微前端框架產(chǎn)品正式落地。

基礎類庫:為解決樣式和編碼規(guī)范統(tǒng)一等問題,需要一系列的基礎類庫,如基礎組件庫,樣式庫等;
微前端底座:提供基礎的admin能力,通過門戶布局組件提供擴展修改能力,底座核心包含注冊中心,資源加載器;
微應用開發(fā)腳手架:提供標準工程結(jié)構(gòu)的開發(fā)腳手架,開發(fā)者可專注于業(yè)務開發(fā),不需重復調(diào)試編譯構(gòu)建等復雜的接入規(guī)范;
低代碼平臺輸出標準微應用:通過低代碼平臺的可視化配置,快速輸出標準的微應用,無縫接入微前端底座。
微前端部署場景示例
微前端的部署有兩種形式,一種是將所有微應用的資源與底座加載器合并成一個文件夾,進行合并部署,只提供一個Web服務;另一種則是將底座和微應用分開部署,每個微應用都提供單獨的Web服務。
合并部署
獨立部署
問題與反思
在微前端框架的實施過程中,遇到的主要問題有如下幾點:
頁面樣式混亂:因為微應用具備獨立開發(fā)的特性,不同團隊開發(fā)的微應用聚合到一起時,無法避免出現(xiàn)頁面混亂、不統(tǒng)一等問題;
團隊協(xié)同性差:伴隨著團隊自治程度的提升,協(xié)作困難等問題隨之產(chǎn)生;
用戶流量負擔:獨立構(gòu)建意味著公共資源的冗余,繼而增加用戶的流量負擔;
問題排查困難:當微應用與加載器底座的對接出現(xiàn)問題時,除框架構(gòu)建者外,開發(fā)人員往往很難定位問題所在。
當前,因為技術(shù)發(fā)展的桎梏,有些問題確實難以短期內(nèi)有效解決,但這也正是我們軟件開發(fā)者們需要不斷為之努力和探索的方向所在。未來,微前端不一定是未來發(fā)展趨勢的收束點,但是它在未來一定會發(fā)揮重要作用。