微前端架構(gòu)實(shí)踐

微前端解決的問(wèn)題

  • 跨框架: 在一個(gè)頁(yè)面上運(yùn)行,可以同時(shí)使用多個(gè)框架
  • 應(yīng)用拆分:將一個(gè)復(fù)雜的應(yīng)用拆解為多個(gè)微小的應(yīng)用,類似后端的微服務(wù)。
  • 遺留系統(tǒng)遷移:讓舊的前端框架可以直接嵌入到現(xiàn)有的應(yīng)用進(jìn)行。

微前端的技術(shù)拆分方式

路由分發(fā)式

通過(guò)HTTP服務(wù)的反向代理功能或者是應(yīng)用框架自帶了的路由,將請(qǐng)求分發(fā)到不同的獨(dú)立前端應(yīng)用上。這種方式適合用來(lái)做遺留系統(tǒng)遷移。

問(wèn)題:

  • 當(dāng)用戶從一個(gè)應(yīng)用到另外一個(gè)應(yīng)用時(shí),需要刷新頁(yè)面、重新加載資源文件。
  • 缺少應(yīng)用狀態(tài)處理。

特點(diǎn):

  • 需要關(guān)注應(yīng)用間的數(shù)據(jù)傳遞方式。從應(yīng)用A傳遞數(shù)據(jù)到應(yīng)用B,如果是這些應(yīng)用是在一個(gè)域里面,則可以通過(guò)LocalStorage、Cookies、IndexedDB等共享數(shù)據(jù)。
  • 一個(gè)頁(yè)面只有一個(gè)應(yīng)用。

使用NGINX路由分發(fā)的例子,如下:

   server {
        listen       80;
        server_name  www.demo.com;

        location /api/ {
            proxy_pass http://127.0.0.1:8080/api;
        }
        location /client {
            proxy_pass http://127.0.0.1:8080/client;
        }
        location /admin {
            proxy_pass http://127.0.0.1:8080/admin;
        }
    }

前端微服務(wù)化

這種方式下,每個(gè)前端應(yīng)用都是相互獨(dú)立的(開(kāi)發(fā)、部署、構(gòu)建、運(yùn)行),然后通過(guò)模塊化的方式組合完整的前端應(yīng)用。

特點(diǎn):

  • 一個(gè)頁(yè)面上可以運(yùn)行多個(gè)前端應(yīng)用。
  • 需要在頁(yè)面合適的地方引入或創(chuàng)建DOM。
  • 用戶操作時(shí),要加載對(duì)應(yīng)的應(yīng)用,也能卸載應(yīng)用(移除DOM和對(duì)應(yīng)應(yīng)用的監(jiān)聽(tīng))。
  • 應(yīng)用間的第三方依賴不能沖突,也就是說(shuō)應(yīng)用A和B不能引入某個(gè)插件的不同版本,如果出現(xiàn)了這樣的沖突,就需要去解決。

實(shí)踐方式:


image.png

如上圖所示,這是個(gè)基座模式,就是通過(guò)一個(gè)主應(yīng)用,來(lái)管理其它應(yīng)用。每個(gè)項(xiàng)目對(duì)基座的要承擔(dān)功能定義不一樣,我看的書里的項(xiàng)目對(duì)基座包含的功能有:(1)管理其他子應(yīng)用(2)負(fù)責(zé)應(yīng)用之間的通信(3)設(shè)計(jì)路由的響應(yīng)機(jī)制(4)支持嵌入常規(guī)和iframe模式??梢杂脕?lái)參考。

image.png

以上的圖是書里的基座設(shè)計(jì)的一個(gè)流程。
(1)應(yīng)用注冊(cè)表的服務(wù)【最右邊】:它是一個(gè)固定值的配置文件,或是一個(gè)可動(dòng)態(tài)更新的配置,或是一種動(dòng)態(tài)的服務(wù)。應(yīng)用注冊(cè)表的服務(wù)主要是為了有以下的一些內(nèi)容:

  • 應(yīng)用發(fā)現(xiàn)。讓主應(yīng)用可以尋找到其它應(yīng)用。
  • 應(yīng)用注冊(cè)。向應(yīng)用注冊(cè)表注冊(cè)新的微前端應(yīng)用功能。
  • 第三方應(yīng)用注冊(cè)。讓第三方應(yīng)用,可以接入到系統(tǒng)中。
  • 訪問(wèn)權(quán)限等相關(guān)配置。
    (2)主工程從服務(wù)器獲取最新的應(yīng)用配置
    (3)主工程獲取配置后,創(chuàng)建應(yīng)用并初始化。
    (4)主工程監(jiān)測(cè)到路由變化,確認(rèn)是否有路由對(duì)應(yīng)的應(yīng)用,找到匹配的應(yīng)用后,加載對(duì)應(yīng)的應(yīng)用。

可用的框架:
Single-SPA: 有大部分框架( React、Angular、Vue 等)的啟動(dòng)和卸載處理。
Mooa:基于 Single-SPA 為 Angular 框架設(shè)計(jì)的一個(gè)微前端架構(gòu)應(yīng)用。

微應(yīng)用

開(kāi)發(fā)的都是單一的微小應(yīng)用,然后通過(guò)工程的方式,在部署構(gòu)建時(shí)把多個(gè)獨(dú)立的應(yīng)用組合成一個(gè)新的單體應(yīng)用。

一個(gè)大的前端項(xiàng)目,往往從文件目錄上就已經(jīng)進(jìn)行了模塊的拆分。這種方式下,就是把各個(gè)模塊加上共享部分的代碼成為一個(gè)單獨(dú)的應(yīng)用。在構(gòu)建整個(gè)前端項(xiàng)目時(shí),復(fù)制所有的模塊到一個(gè)項(xiàng)目中,進(jìn)行集成構(gòu)建。

問(wèn)題:

  • 只能使用統(tǒng)一的前端框架。
  • 所有應(yīng)用的依賴版本要統(tǒng)一。
  • 非常依賴于持續(xù)集成,只要有一個(gè)子應(yīng)用更新了,就需要重新構(gòu)建整個(gè)應(yīng)用。

實(shí)踐例子:
1.有一個(gè)主代碼庫(kù),這個(gè)代碼庫(kù)里是一個(gè)空白的angular框架代碼,可以獨(dú)立構(gòu)建包含另外幾個(gè)應(yīng)用的完整代碼。
2.manager應(yīng)用,這個(gè)應(yīng)用內(nèi)是一個(gè)完整的angular應(yīng)用,是可以獨(dú)立開(kāi)發(fā)運(yùn)行的。
3.各個(gè)應(yīng)用,同2.
4.構(gòu)建過(guò)程:(1)從遠(yuǎn)程拉取最新代碼;(2)更新子應(yīng)用代碼到主應(yīng)用中的占位模塊:把manager等子應(yīng)用對(duì)應(yīng)的模塊和代碼copy到主工程中,其實(shí)就是拷貝manager路徑下的代碼到主工程中。(3)可能還會(huì)有一些文本替換的內(nèi)容。
5.持續(xù)集成:子應(yīng)用代碼有更新就要出發(fā)對(duì)應(yīng)模塊的構(gòu)建,構(gòu)建完成再觸發(fā)整個(gè)系統(tǒng)的構(gòu)建;主應(yīng)用代碼更新觸發(fā)整個(gè)系統(tǒng)的構(gòu)建。如果為了避免頻繁的構(gòu)建,可以考慮定時(shí)構(gòu)建的方式。

微件化

微件(Widget)指的是可以直接嵌入應(yīng)用,能運(yùn)行的代碼,需要預(yù)編譯好。
Widget的形式有:

  • 分包構(gòu)建出來(lái)的獨(dú)立代碼,例如webpack構(gòu)建出來(lái)的chunk文件。
  • 使用DSL方式編寫出來(lái)的組件。

特點(diǎn):

  • 必須要有一個(gè)基礎(chǔ)的完整的框架來(lái)運(yùn)行和編譯環(huán)境,確保Widget是可用的?!?39頁(yè)(第一行運(yùn)行時(shí)及編譯環(huán)境)】
  • 需要規(guī)劃好依賴,當(dāng)一個(gè)Widget想要使用新的依賴,需要在上游中引入這個(gè)依賴。
  • 需要一個(gè)能用于構(gòu)建獨(dú)立Widget模塊的構(gòu)建系統(tǒng),所以需要改寫webpack,使得它能支持構(gòu)建出單個(gè)代碼段。

問(wèn)題:

  • 因?yàn)槭沁\(yùn)行時(shí)才編譯的,所以對(duì)比于預(yù)先編譯的應(yīng)用,性能方面會(huì)受影響。
  • 實(shí)施成本比微應(yīng)用化高。

實(shí)踐:


image.png

如上圖,在實(shí)踐中,編寫不同的業(yè)務(wù)代碼,將部分業(yè)務(wù)功能構(gòu)建成獨(dú)立的chunk代碼,把編譯好的代碼放到指定的服務(wù)器上【微件中心】。運(yùn)行時(shí),只需要加載對(duì)應(yīng)的業(yè)務(wù)模塊代碼就可以了。更新的時(shí)候同樣只需要更新對(duì)應(yīng)模塊的代碼。

前端容器化(iframe)

將iframe作為容器來(lái)容納其他前端應(yīng)用。iframe可以把另一個(gè)網(wǎng)頁(yè)或者單頁(yè)面應(yīng)用嵌入當(dāng)前頁(yè)面中,并且iframe中的網(wǎng)頁(yè)和其他網(wǎng)頁(yè)相互獨(dú)立。使用iframe需要設(shè)計(jì)好加載機(jī)制和通信機(jī)制,也就是說(shuō)要定義好什么時(shí)候加載、卸載應(yīng)用;通信的事件名規(guī)范是什么、什么時(shí)候去監(jiān)聽(tīng)/解綁事件監(jiān)聽(tīng)。

特點(diǎn):

  • 網(wǎng)站不需要SEO支持。
  • 兼容性良好。

應(yīng)用組件化

借助于Web Components技術(shù),來(lái)構(gòu)建跨框架的前端應(yīng)用。
Web Components可以允許我們創(chuàng)建可重用的定制元素,并且在web應(yīng)用中使用它們。Angular框架中已經(jīng)支持把當(dāng)前應(yīng)用構(gòu)建成一個(gè)Web Components組件了。React也能夠支持引入Web Components組件。實(shí)踐中,還需要構(gòu)建出Web Components組件,然后在頁(yè)面中引入這些Web Components組件,使用方式有點(diǎn)像微件化。

Web Components是由Custom Elements、Shadow Dom、HTML Templates、HTML Imports組成的。

問(wèn)題:

  • Web Components瀏覽器的兼容性還沒(méi)有很高。


    image.png

選擇哪一種微前端方案

可以參考《前端架構(gòu):從入門到微前端》的作者博客:微前端架構(gòu)選型指南

學(xué)習(xí)書籍:
《前端架構(gòu):從入門到微前端》

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 采用微前端架構(gòu) 原文 考慮到關(guān)于微前端的第一篇文章的大量反饋,以及我們?cè)?DAZN 采用的方式收到的問(wèn)題,我決定分...
    云峰yf閱讀 880評(píng)論 0 4
  • 什么是微前端 微前端是一種類似于微服務(wù)的架構(gòu),它將微服務(wù)的理念應(yīng)用于瀏覽器端,即將 Web 應(yīng)用由單一的單體應(yīng)用轉(zhuǎn)...
    belllee閱讀 24,027評(píng)論 0 17
  • 前端集成解決方案要求: 模塊化開(kāi)發(fā)。最好能像寫nodejs一樣寫js,很舒服。css最好也能來(lái)個(gè)模塊化管理! 性能...
    Www劉閱讀 3,240評(píng)論 1 20
  • 在過(guò)去的幾個(gè)星期里,隨著 Martin Fowler 博客上那篇 Cam Jackson 寫的微前端的文章發(fā)布,到...
    ThoughtWorks閱讀 1,157評(píng)論 0 1
  • 網(wǎng)站的SEO頁(yè)面的要求 你做對(duì)了嗎? 在做網(wǎng)站優(yōu)化中很對(duì)人對(duì)于頁(yè)面不太重視,覺(jué)得只要搞好整體的優(yōu)化布局和關(guān)鍵詞密度...
    4ffde5305e8f閱讀 377評(píng)論 0 0

友情鏈接更多精彩內(nèi)容