如何瓦解巨石單頁應用

以前經過幾篇文章像你們介紹了我是如何經過微前端的手段去治理一個有幾十個子業務域系統的大型 B 端系統。今天我想經過這篇文章來像你們介紹下我是如何在這樣一個大型 B 端系統中去治理一個「巨石」單頁子業務系統的。前端

先聊聊背景

做爲一個前端咱們大體都經歷過早期的 MPA 應用演變爲 SPA 應用的體驗快感,也相信你們都經歷過簡單 SPA 演變爲巨石 SPA 的痛苦。目前我在負責一個大型 B 端系統的一個子業務,這個子業務是一個大型的 SPA,3W+代碼行數,子頁面入口有 10+。而且由於業務屬性的類似性,這個子業務系統還做爲子系統服務於其餘兩個系統平臺。從我平日的迭代開發來看,這樣的應用已經「大到快不能維護了」,開發維護成本極高。npm

接下來我會像你們簡單介紹,在拿到這樣一個「巨石「單頁應用,我是如何一步步作項目拆分優化治理的。數據結構

分析業務邊界

首先我以爲要作的就是理清楚業務邊界,咱們的業務雖然做爲大型 B 端系統的一個子業務,可是咱們的系統內部也能夠根據業務邊界拆分紅多個細分的子系統,接下來我從一個例子提及。架構

假設咱們當前的業務大致以下所示,業務功能聚合在子 tab 下,每一個 tab 下都有着複雜的業務邏輯,而且咱們的系統也做爲子業務服務於平臺 A、B、C。
函數

這時候作系統拆分的時候,很直觀的就會聯想到根據平臺 A、B、C 把咱們的系統拆分爲三個業務子系統。若是說,咱們的業務平臺差別性很大,那麼按照平臺屬性去作系統拆分無可厚非。可是我相信業界的 FEer 們都更傾向於 「one code,any platform」,那麼咱們的業務在這些平臺都差別不大,甚至說只是主題色的差別,那麼按照平臺去作系統拆分就顯得很不合理了。佈局

接下來,咱們能夠考慮從頁面結構來作系統拆分,能夠看出目前咱們應用的結構以 tab 的形式分別聚合。若是此時各個 tab 間沒有複雜的事件通訊等,即可以考慮以此來拆分咱們的子模塊。post

最後還差一步,就是咱們的業務屬性的分析,能夠更進一步的從當前的產品邏輯來入手,將更貼合或者說彼此耦合度較高的一些產品功能做爲一個子模塊放到一塊兒,這樣會更加利於將來代碼的擴展和維護。優化

在咱們作業務拆分的時候常常會面臨着取捨,有不少細碎的小業務不知道劃分到哪一個子模塊裏,這裏我說一個我常常用的方法:我會盡可能保持核心業務模塊的獨立性,把相對無關的子業務拆分到一塊兒,想一想由於一個八竿子打不着的業務影響到核心業務你們都不想吧...spa

這裏簡單總結下:架構設計

  • 分析平臺差別,平臺差別大能夠根據平臺拆分;
  • 分析頁面結構,若是結構清晰,能夠根據結構拆分;
  • 分析產品業務,將產品邏輯耦合度高的功能合併到一塊兒;

拆分公共依賴

在咱們理清了業務邊界劃分了業務模塊以後,不要着急着去作模塊拆分,這時候咱們能夠從這些即將要拆分的子業務模塊中去找到公共依賴。

接下來簡單說下我在當前業務的一個依賴拆分思路:

  • 針對視圖層,咱們落地了組內的業務組件庫,在已有 UI 組件庫以外抽離了一些具備業務特徵的基礎業務原子組件,而後是基於原子組件封裝一些複雜的業務域特有的業務組件,這些業務組件不只服務與咱們自有的業務,在其餘業務域與咱們業務的交集中也能夠用到。
  • 針對邏輯層,咱們落地了業務函數庫,裏面包含了咱們業務域通用的函數功能,接口數據結構 to 組件數據結構的各類 adapter 函數等等。

那麼此時咱們的系統就以下圖所示:

拆分子業務模塊

在梳理了業務邊界和公共依賴的拆分以後,就是真正的子模塊的拆分,這裏我主要想說的就是怎麼把拆開的各模塊「聚合」起來。

不一樣於以前聊過的 B 端系統的治理,咱們子系統中子業務模塊的聚合沒有太多的約束:

  • 業務體量大不過整個 B 端系統,不須要複雜的路由設計
  • 不須要考慮和其餘業務域間的影響,宿主環境已經爲咱們作好了沙箱隔離;
  • 能夠設計本身的通訊方案,也能夠適當複用宿主環境的通訊方案(由於作好了業務邊界的劃分,子業務模塊間理論上不該該存在複雜的通訊場景了);

可是咱們也須要針對宿主環境的架構方案來制定本身的聚合方案,這裏我列舉下目前咱們嘗試過的可行方案:

基於 npm 包架構

這種架構致力於將通用的佈局組件拆分爲 npm 包的形式提供給子應用。這樣的架構具備如下的優勢:

  • 開發落地簡單,子應用單獨開發單獨部署,僅須要引入佈局組件便可;
  • 不依賴宿主環境,宿主環境能夠採起任意架構,這種方案都不會受到太大的影響;

可是也會有如下的缺點:

  • 佈局組件中不能包含太重的業務邏輯,頻繁的業務更迭將致使子應用須要頻繁同步更新組件版本。
  • 畢竟是基於 MPA,相比於其餘兩種方案的無刷體驗差些。

基於 iframe 架構

這種方案我就不贅述了,以前的文章已經有較爲詳細的架構分析了。這裏我直接列舉下區別於當前場景的一些缺點:

  • 依賴宿主環境的架構,若是宿主環境也是 iframe 架構,那麼一層層的 iframe 嵌套比較蛋疼;

基於微前端架構

同理,這種方案我就不贅述了,以前的文章已經有較爲詳細的架構分析了。這裏我直接列舉下區別於當前場景的一些缺點:

  • 依賴宿主環境的架構,若是宿主也是微前端架構,由於目前我尚未嘗試過微前端嵌套的場景,可行性以及將來的風險不可控。若是宿主是 iframe 架構,其實這也是一個不錯的方案(徹底的沙箱隔離),目前咱們組內也有此種方案的嘗試和落地;

最後,咱們的應用按照以下層次進行拆分:

結語

以上即是我對大型 SPA 進行分層治理的一些思考,固然我所介紹的只是萬千應用中的一種場景,而且真實拆分的過成功遇到的問題也比文中描述的多得多,路子不少,但願你們都能找到適合本身應用的架構設計。

推薦閱讀

相關文章
相關標籤/搜索