介紹
什么是前端微服務?我們知道,近些年,前端發展呈百家爭鳴式發展,框架層出不窮,版本更是迭代不窮,難免會出現前端項目技術棧不統一、所用框架版本不統一。比如,有的項目中,還采用了angelar1.0、vue1.0等。而這些項目若沒有新的功能加入,線上穩定運行,對其重構成本會很高。但卻需要結合到新的應用中去,遇到的較多的情況是:舊的應用使用的是 Angular.js 編寫,而新的應用開始采用 Angular 2+。這對於業務穩定的團隊來說,是極為常見的技術棧。在即不重寫原有系統的基礎之下,又可以抽出人力來開發新的業務。其不僅僅對於業務人員來說, 是一個相當吸引力的特性;對於技術人員來說,不重寫舊的業務,同時還能做一些技術上的挑戰,也是一件相當有挑戰的事情。
而前端微服務的一個賣點也在這里,去兼容不同類型的前端框架。除此之外,在這兩三年里,移動應用出現了一種趨勢,用戶不想裝那么多應用了。而往往一家大的商業公司,會提供一系列的應用。這些應用也從某種程度上,反應了這家公司的組織架構。然而,在用戶的眼里他們就是一家公司,他們就只應該有一個產品。相似的,這種趨勢也在桌面 Web 出現。聚合成為了一個技術趨勢,體現在前端的聚合就是微服務化架構。
實現方案
理想的前端微服務化,應該是符合下面幾個特點:
- 獨立部署
- 獨立開發
- 技術無關
- 不影響用戶體驗
其實現方式:
- 使用 HTTP 服務器的路由來重定向多個應用,即路由分發
- 在不同的框架之上設計通訊、加載機制,諸如Single-SPA 和 Mooa
- 通過組合多個獨立應用、組件來構建一個單體應用
- iFrame。使用 iFrame 及自定義消息傳遞機制
- 使用純 Web Components 構建應用
路由分發
路由分發式微前端,即通過路由將不同的業務分發到不同的、獨立前端應用上。其通常可以通過 HTTP 服務器的反向代理來實現,又或者是應用框架自帶的路由來解決。
就當前而言,通過路由分發式的微前端架構應該是采用最多、最易采用的 “微前端” 方案。但是這種方式看上去更像是多個前端應用的聚合,即我們只是將這些不同的前端應用拼湊到一起,使他們看起來像是一個完整的整體。但是它們並不是,每次用戶從 A 應用到 B 應用的時候,往往需要刷新一下頁面。通常可通過nginx配置反向代理,來進行路由分發,從而實現前端微服務
它適用於以下場景:
- 不同技術棧之間差異比較大,難以兼容、遷移、改造
- 項目不想花費大量的時間在這個系統的改造上
- 現有的系統在未來將會被取代
- 系統功能已經很完善,基本不會有新需求
- 應用切換時,刷新整個頁面
而在滿足上面場景的情況下,如果為了更好的用戶體驗,還可以采用 iframe 的方式來解決。
使用 iFrame 創建容器
iframe 可以創建一個全新的獨立的宿主環境,這意味着我們的前端應用之間可以相互獨立運行。采用 iframe 有幾個重要的前提:
- 網站不需要 SEO 支持
- 需要設置加載機制
- 需要設置通訊機制
即何時加載、卸載應用,如何監聽應用事件等。
框架之上設計通訊、加載機制
不論是基於 Web Components 的 Angular,或者是 VirtualDOM 的 React 等,現有的前端框架都離不開基本的 HTML 元素 DOM。
那么,我們只需要:
- 在頁面合適的地方引入或者創建 DOM
- 用戶操作時,加載對應的應用(觸發應用的啟動),並能卸載應用。
第一個問題,創建 DOM 是一個容易解決的問題。而第二個問題,則一點兒不容易,特別是移除 DOM 和相應應用的監聽。當我們擁有一個不同的技術棧時,我們就需要有針對性設計出一套這樣的邏輯。現有的框架有single-spa、qiankun、mooa等
通過組合多個獨立應用、組件來構建一個單體應用
常見的方式有:
- 獨立構建組件和應用,生成 chunk 文件,構建后再歸類生成的 chunk 文件。(這種方式更類似於微服務,但是成本更高)
- 開發時獨立開發組件或應用,集成時合並組件和應用,最后生成單體的應用。
- 在運行時,加載應用的 Runtime,隨后加載對應的應用代碼和模板。
但是,首先它有一個嚴重的限制:必須使用同一個框架。
其次,采用這種方式還有一個限制,那就是:規范!**規范!**規范!。在采用這種方案時,我們需要:
- 統一依賴。統一這些依賴的版本,引入新的依賴時都需要一一加入。
- 規范應用的組件及路由。避免不同的應用之間,因為這些組件名稱發生沖突。
- 構建復雜。在有些方案里,我們需要修改構建系統,有些方案里則需要復雜的架構腳本。
- 共享通用代碼。這顯然是一個要經常面對的問題。
- 制定代碼規范。
純 Web Components 技術構建
Web Components 組件可以擁有自己獨立的 Scripts
和 Styles
,以及對應的用於單獨部署組件的域名。然而它並沒有想象中的那么美好,要直接使用純 Web Components 來構建前端應用的難度有:
- 重寫現有的前端應用。是的,現在我們需要完成使用 Web Components 來完成整個系統的功能。
- 上下游生態系統不完善。缺乏相應的一些第三方控件支持,這也是為什么 jQuery 相當流行的原因。
- 系統架構復雜。當應用被拆分為一個又一個的組件時,組件間的通訊就成了一個特別大的麻煩。
- 瀏覽器兼容問題
現有框架
現有的微前端框架有single-spa、qiankun、mooa。其均是在前端框架之上設計通訊、加載機制來實現的。
其中single-spa已經實現了大部分框架(vue、react、angular)的啟動和卸載處理,但不適用於生產環境
qiankun是基於spa-single實現的以運行在生產環境為目標的微前端服務框架
Mooa是一個僅僅基於angular框架的微前端框架
截止到20191102,其star數如下
- single-spa https://github.com/CanopyTax/single-spa 4132stars
- qiankun https://github.com/umijs/qiankun 1700stars
- mooa https://github.com/phodal/mooa 482stars
其具體使用,可參考官方文檔