1. 程式人生 > >拆分大型 Angular 應用四種策略

拆分大型 Angular 應用四種策略

上一個月,我們花了大量的時間設計方案來拆分一個大型的 Angular 應用。從使用 Angular 的 Lazyload 到前端微服務化,進行了一系列的討論。最後,我們終於有了結果,採用的是 Lazyload 變體:構建時整合程式碼 的方式。

主要是為了達成以下的設計目標:

  • 構建外掛化的 Web 開發平臺,滿足業務快速變化及分散式多團隊並行開發的需求

  • 構建服務化的中介軟體,搭建高可用及高複用的前端微服務平臺

  • 支援前端的獨立交付及部署

簡單地來說,就是要支援應用外掛化開發,以及多團隊並行開發

應用外掛化開發,其所要解決的主要問題是:臃腫的大型應用的拆分問題。大型前端應用,在開發的時候要面臨大量的遺留程式碼

、不同業務的程式碼耦合在一起,在線上的時候還要面臨載入速度慢,執行效率低的問題。

最後就落在了兩個方案上:路由懶載入及其變體前端微服務化

前端微服務化:路由懶載入及其變體

路由懶載入,即通過不同的路由來將應用切成不同的程式碼快,當路由被訪問的時候,才載入對應元件。在諸如 Angular、Vue 框架裡都可以通過路由 + Webpack 打包的方式來實現。而,不可避免地就會需要一些問題:

難以多團隊並行開發,路由拆分就意味著我們仍然是在一個原始碼庫裡工作的。也可以嘗試拆分成不同的專案,再編譯到一起。

每次釋出需要重新編譯,是的,當我們只是更新一個子模組的程式碼,我們要重新編譯整個應用,再重新發布這個應用。而不能獨立地去構建它,再發布它。

統一的 Vendor 版本,統一第三方依賴是一件好事。可問題的關鍵在於:每當我們新增一個新的依賴,我們可能就需要開會討論一下。

然而,標準 Route Lazyload 最大的問題就是難以多團隊並行開發,這裡之所以說的是 “難以” 是因為,還是有辦法解決這個問題。在日常的開發中,一個小的團隊會一直在一個程式碼庫裡開發,而一個大的團隊則應該是在不同的程式碼庫裡開發。

於是,我們在標準的路由懶載入之上做了一些嘗試。

微服務化方案:子應用模式

除了路由懶載入,我們還可以採用子應用模式,即每個應用都是相互獨立地。即我們有一個基座工程,當用戶點選相應的路由時,我們去載入這個獨立 的 Angular 應用;如果是同一個應用下的路由,就不需要重複載入了。而且,這些都可以依賴於瀏覽器快取來做。

除了路由懶載入,還可以採用的是類似於 Mooa 的應用嵌入方案。如下是基於 Mooa 框架 + Angular 開發而生成的 HTML 示例:

  1. <app-root _nghost-c0=""ng-version="4.2.0">

  2.  ...

  3. <app-home _nghost-c2="">

  4. <app-app1 _nghost-c0=""ng-version="5.2.8"style="display: none;"><nav _ngcontent-c0=""class="navbar"></app-app1>

  5. <iframeframeborder=""width="100%"height="100%"src="http://localhost:4200/app/help/homeassets/iframe.html"id="help_206547"></iframe>

  6. </app-home>

  7. </app-root>

Mooa 提供了兩種模式,一種是基於 Single-SPA 的實驗做的,在同一頁面載入、渲染兩個 Angular 應用;一種是基於 iFrame 來提供獨立的應用容器。

解決了以下的問題:

  • 首頁載入速度更快,因為只需要載入首頁所需要的功能,而不是所有的依賴。

  • 多個團隊並行開發,每個團隊裡可以獨立地在自己的專案裡開發。

  • 獨立地進行模組化更新,現在我們只需要去單獨更新我們的應用,而不需要更新整個完整的應用。

但是,它仍然包含有以下的問題:

  • 重複載入依賴項,即我們在 A 應用中使用到的模組,在 B 應用中也會重新使用到。有一部分可以通過瀏覽器的快取來自動解決。

  • 第一次開啟對應的應用需要時間,當然預載入可以解決一部分問題。

  • 在非 iframe 模式下執行,會遇到難以預料的第三方依賴衝突。

於是在總結了一系列的討論之後,我們形成了一系列的對比方案:

方案對比

在這個過程中,我們做了大量的方案設計與對比,便想寫一篇文章對比一下之前的結果。先看一下圖:

640?wx_fmt=jpeg

Angular 程式碼拆分對比

表格對比:

640?wx_fmt=png

詳細的介紹如下:

標準 LazyLoad

開發流程:多個團隊在同一個程式碼庫裡開發,構建時只需要拿這一份程式碼去部署。

行為:開發、構建、執行一體

適用場景:單一團隊,依賴庫少、業務單一

LazyLoad 變體 1:構建時整合

開發流程:多個團隊在同不同的程式碼庫裡開發,在構建時將不同程式碼庫的程式碼整合到一起,再去構建這個應用。

適用場景:多團隊,依賴庫少、業務單一

變體-構建時整合:開發分離,構建時整合,執行一體

LazyLoad 變體 2:構建後集成

開發流程:多個團隊在同不同的程式碼庫裡開發,在構建時將編譯成不同的幾份程式碼,執行時會通過懶載入合併到一起。

適用場景:多團隊,依賴庫少、業務單一

變體-構建後集成:開發分離,構建分離,執行一體

前端微服務化

開發流程:多個團隊在同不同的程式碼庫裡開發,在構建時將編譯成不同的幾個應用,執行時通過主工程載入。

適用場景:多團隊,依賴庫多、業務複雜

前端微服務化:開發、構建、執行分離

總對比

總體的對比如下表所示:

640?wx_fmt=png

So,你怎麼看呢?

掃碼關注最新前端技術實踐

640?wx_fmt=png

感謝支援~~

640?wx_fmt=jpeg