將巨石應用拆分為多個子應用,提升開發效率與體驗

游客2024-07-07 09:30:01

 1

目錄前言

目前,基於vue、react、 的單頁應用程式開發模式已成為業界主流。受益於它們豐富的生態,我們可以使用這些技術快速建立一個新的應用,迅速回應市場。隨著公司業務的不斷發展,應用開始變得龐大臃腫,逐漸成為一個巨石應用,難以維護不說,每次開發、上線新需求時還需要花費不少的時間來構建項目,對開發人員的開發效率和體驗都造成了不好的影響。因此將一個巨石應用拆分為多個子應用勢在必行。

一般情況下,我們會基於業務來拆分應用程式。每個應用程式都有一個自己的倉庫,獨立開發、獨立部署、獨立存取、獨立維護,還可以根據團隊的特點自主選擇適合自己的技術棧,極大的提升了開發人員的效率和體驗。

應用拆分能為我們帶來便利,但同時也為我們帶來了新的挑戰,那就是應用程式的聚合。對於客戶來說,他們在使用我們的產品時,更希望呈現在自己面前的是一個完整的應用,而不是分散的多個子應用。因此我們需要選擇一個合適的方案,能相容於不同的技術棧,將已經拆分的子應用重新聚合。

而微前端,正是這樣一個合適的方案,來幫助我們面對上述挑戰。

什麼是微前端

微前端,早已是老生常談的概念,它於2016 年首次出現在Radar 上,將後端微服務的概念擴展到了前端世界。

微服務,維基上對其定義為:一種軟體開發技術- 面向服務的體系結構(SOA)架構樣式的一種變體,將應用程式構造為一組鬆散耦合的服務,並通過輕量級的通信協定組織起來。具體來講,就是將一個單體應用,依照一定的規則拆分為一組服務。這些服務,各自擁有自己的倉庫,可以獨立開發、獨立部署,有獨立的邊界,可以由不同的團隊來管理,甚至可以使用不同的程式語言來編寫。但對前端來說,仍然是一個完整的服務。

微服務,主要是用來解決龐大的一整塊後端服務所帶來的變更和擴展的限制。

同樣的,面對越來越重的前端應用,可將微服務的思想照搬到前端,就有了微前端的概念。像微服務一樣,一個前端應用,也可以依照一定的規則,拆分為不同的子應用,獨立開發,獨立部署,然後聚合成一個完整的應用面對客戶。

微前端的一般結構如下:

 2

上圖摘取自微前端到底是什麼。

微前端能帶給我們什麼使用微前端時所面臨的挑戰

微前端方案帶給我們巨大便利的同時,也為我們帶來了新的挑戰。在實現微前端應用時,我們必須要考慮以下問題:

微前端常用技術方案

目前,業界主流的微前端實現方案主要有:

路由分發式微前端

路由分發式微前端,即透過路由將不同的業務分發到不同的獨立前端應用上。最常用的方案是透過HTTP 服務的反向代理來實現。

下面是一個基於路由分發的Nginx 設定:

 http {
        server {
            listen 80;
            server_name  xxx.xxx.com;
            location /api/ {
                proxy_pass http://localhost:3001/api;
            }
            location /web/admin {
                proxy_pass http://localhost:3002/api;
            }
            location / {
                proxy_pass /;
            }
        }
    }

透過上述配置,不同頁面的請求就可以分送到不同的伺服器上。

優點:

缺點:

作為一項非常古老的技術,也可以用來實現微前端。透過,我們可以很方便的將一個應用程式嵌入到另一個應用程式中,而且兩個應用程式之間的css 和是相互隔離的,不會互相干擾。

優點:

缺點:

-spa

路由轉送模式、 模式儘管可以實現微前端,但是體驗不好。我們每次切換回已經造訪過的子應用程式時,都需要重新載入子應用,對效能有很大的影響。

我們知道,現在前端應用程式開發的主流模式為基於vue / react/ 的單頁應用程式開發模式。在這個模式下,我們需要維護一個路由註冊表,每個路由對應各自的頁面元件url。切換路由時,如果是新的頁面,需要動態取得路由對應的js 腳本,然後執行腳本並渲染出對應的頁面;如果是一個已經造訪過的頁面,那麼直接從快取中取得已快取的頁面方法,執行並渲染出對應的頁面。

那麼,微前端也有沒有類似的實作方案,來獲得和單頁應用一樣的使用者體驗呢?

答案是有的。 -spa 提供了新的技術方案,可以幫助我們實現類似單頁應用的體驗。

在-spa 方案中,應用被分為兩類:基座應用和子應用。其中,子應用就是文章上面描述的需要聚合的子應用;而基座應用,是另外的一個單獨的應用,用於聚合子應用。

和單頁應用程式的實作原理類似,-spa 會在基座應用中維護一個路由註冊表,每個路由對應一個子應用程式。基座應用程式啟動以後,當我們切換路由時,如果是一個新的子應用,會動態獲取子應用的js 腳本,然後執行腳本並渲染出相應的頁面;如果是一個已經訪問過的子應用,那麼就會從快取中取得已經快取的子應用,啟動子應用程式並渲染出對應的頁面。

在這裡,本文僅對-spa 做初步的介紹,如需深入了解,詳見官網:-spa 和微前端學習系列(二):-spa。

優點:

缺點:

和-spa 一樣, 也能給我們提供類似單頁應用程式的使用者體驗。 是在-spa 的基礎上做了二次開發,在框架層面解決了使用-spa 時需要開發人員自己編寫子應用加載、通信、隔離等邏輯的問題,是一種比-spa 更優秀的微前端方案。

在這裡,本文同樣僅對做簡單的說明,如需深入了解,詳見官網: 和微前端學習系列(三):。

優點:

缺點:

新發布的,提供了一個新的特性- 。基於這個特性,我們可以在一個應用程式中動態載入並運行另一個應用程式的程式碼,並實現應用程式之間的依賴共享。

透過,我們可以在一個應用程式裡面動態渲染另一個應用程式的頁面,這樣也實現了多個子應用程式的聚合。

的用法詳見微前端學習系列(四): 。

優點:

缺點:

Web

基於Web 的Dom 能力,我們也可以實現微前端,將多個子應用程式聚合起來。

Dom 的用法如下:

const shadow = document.querySelector('#hostElement').attachShadow({mode: 'open'});
// url 为应用的地址,基于 fetch,我们可以获取到应用的 html 模板,添加到指定节点下
fetch(url).then(res => {
    shadow.innerHTML = res
});

優點:

缺點:

結束語

到這裡,微前端的介紹就結束了。本文是微前端學習系列的開篇,之後我們會陸續推出微前端學習系列: -spa、微前端學習系列: 、 , 希望透過這些文章的學習,能讓大家對微前端有一個比較深刻的認識,。

本文的參考資料: