微前端簡(jiǎn)介

什么是微前端

微前端是一種類(lèi)似于微服務(wù)的架構(gòu),它將微服務(wù)的理念應(yīng)用于瀏覽器端,即將 Web 應(yīng)用由單一的單體應(yīng)用轉(zhuǎn)變?yōu)槎鄠€(gè)小型前端應(yīng)用聚合為一的應(yīng)用。各個(gè)前端應(yīng)用可以獨(dú)立運(yùn)行、獨(dú)立開(kāi)發(fā)、獨(dú)立部署。

微前端的概念由ThoughtWorks于2016年提出,此后很快被業(yè)界所接受,并在各互聯(lián)網(wǎng)大廠中得到推廣和應(yīng)用。
微服務(wù)與微前端有很多相似之處,都是希望將某個(gè)單一的單體應(yīng)用,轉(zhuǎn)化為多個(gè)可以獨(dú)立運(yùn)行、獨(dú)立開(kāi)發(fā)、獨(dú)立部署、獨(dú)立維護(hù)的服務(wù)或者應(yīng)用的聚合,從而滿(mǎn)足業(yè)務(wù)快速變化及分布式多團(tuán)隊(duì)并行開(kāi)發(fā)的需求。微服務(wù)與微前端不僅僅是技術(shù)架構(gòu)的變化,還包含了組織方式、溝通方式的變化。微服務(wù)與微前端原理和軟件工程,面向?qū)ο笤O(shè)計(jì)中的原理同樣相通,都是遵循單一職責(zé)(Single Responsibility)、關(guān)注分離(Separation of Concerns)、模塊化(Modularity)與分而治之(Divide & Conquer)等基本的原則。

微前端的優(yōu)缺點(diǎn)

優(yōu)點(diǎn)

微前端如此受到重視,是由于其特點(diǎn)為開(kāi)發(fā)團(tuán)隊(duì)帶來(lái)了大量的收益。下面就分別描述一下其優(yōu)點(diǎn)。

可以與時(shí)俱進(jìn),不斷引入新技術(shù)/新框架

前端技術(shù)棧日新月異,推陳出新的速度絕對(duì)是冠絕群雄。如何在維護(hù)好遺留系統(tǒng)的前提下,不斷引入新技術(shù)和新框架,提高開(kāi)發(fā)效率、質(zhì)量、用戶(hù)體驗(yàn),成為每個(gè)團(tuán)隊(duì)需要認(rèn)真對(duì)待的問(wèn)題。微前端可以很好的實(shí)現(xiàn)應(yīng)用和服務(wù)的隔離,互相之間幾乎沒(méi)有影響,可以很好的支持團(tuán)隊(duì)引入新技術(shù)和新框架。

局部/增量升級(jí)

對(duì)于許多組織來(lái)說(shuō),追求增量升級(jí)就是他們邁向微前端的第一步。對(duì)他們來(lái)說(shuō),老式的大型單體前端要么是用老舊的技術(shù)棧打造的,要么就充斥著匆忙寫(xiě)成的代碼,已經(jīng)到了該重寫(xiě)整個(gè)前端的時(shí)候了。一次性重寫(xiě)整個(gè)系統(tǒng)風(fēng)險(xiǎn)很大,我們更傾向一點(diǎn)一點(diǎn)換掉老的應(yīng)用,同時(shí)在不受單體架構(gòu)拖累的前提下為客戶(hù)不斷提供新功能。

為了做到這一點(diǎn),解決方案往往就是微前端架構(gòu)了。一旦某個(gè)團(tuán)隊(duì)掌握了在幾乎不影響舊世界的同時(shí)為生產(chǎn)環(huán)境引入新功能的訣竅,其他團(tuán)隊(duì)就會(huì)紛紛效仿?,F(xiàn)有代碼仍然需要繼續(xù)維護(hù)下去,但在某些情況下還要繼續(xù)添加新功能,現(xiàn)在總算有了解決方案。

到最后,我們就能更隨心所欲地改動(dòng)產(chǎn)品的各個(gè)部分,并逐漸升級(jí)我們的架構(gòu)、依賴(lài)關(guān)系和用戶(hù)體驗(yàn)。當(dāng)主框架發(fā)生重大變化時(shí)每個(gè)微前端模塊都可以按需升級(jí),不需要整體下線或一次性升級(jí)所有內(nèi)容。如果我們想要嘗試新的技術(shù)或互動(dòng)模式,也能在隔離度更好的環(huán)境下做試驗(yàn)。

代碼簡(jiǎn)潔、解耦、更易維護(hù)

微前端體系下,每個(gè)小模塊的代碼庫(kù)要比一個(gè)單體前端的代碼庫(kù)小很多。對(duì)開(kāi)發(fā)者來(lái)說(shuō)這些較小的代碼庫(kù)處理起來(lái)更簡(jiǎn)單方便。而且微前端還能避免無(wú)關(guān)組件之間不必要的耦合,讓代碼更簡(jiǎn)潔。我們可以在應(yīng)用的限界上下文處劃出更明顯的界限,更好地避免無(wú)意間造成的這類(lèi)耦合問(wèn)題。

獨(dú)立部署

就像微服務(wù)一樣,微前端的一大優(yōu)勢(shì)就是可獨(dú)立部署的能力。這種能力會(huì)縮減每次部署涉及的范圍,從而降低了風(fēng)險(xiǎn)。不管你的前端代碼是在哪里托管,怎樣托管,各個(gè)微前端都應(yīng)該有自己的持續(xù)交付管道;這些管道可以將微前端構(gòu)建、測(cè)試并部署到生產(chǎn)環(huán)境中。我們?cè)诓渴鸶鱾€(gè)微前端時(shí)幾乎不用考慮其他代碼庫(kù)或管道的狀態(tài);就算舊的單體架構(gòu)采用了固定、手動(dòng)的按季發(fā)布周期,或者隔壁的團(tuán)隊(duì)在他們的主分支里塞進(jìn)了一個(gè)半成品或失敗的功能,也不影響我們的工作。如果某個(gè)微前端已準(zhǔn)備好投入生產(chǎn),那么它就能順利變?yōu)楫a(chǎn)品,且這一過(guò)程完全由開(kāi)發(fā)和維護(hù)它的團(tuán)隊(duì)主導(dǎo)

組織更具擴(kuò)展能力,其團(tuán)隊(duì)更加獨(dú)立自治。

解藕代碼庫(kù)、分離發(fā)布周期還能帶來(lái)一個(gè)高層次的好處,那就是大幅提升團(tuán)隊(duì)的獨(dú)立性;一支獨(dú)立的團(tuán)隊(duì)可以自主完成從產(chǎn)品構(gòu)思到最終發(fā)布的完整流程,有足夠的能力獨(dú)立向客戶(hù)交付價(jià)值,從而可以更快、更高效地工作。為了實(shí)現(xiàn)這一目標(biāo)需要圍繞垂直業(yè)務(wù)功能,而非技術(shù)功能來(lái)打造團(tuán)隊(duì)。一種簡(jiǎn)單的方法是根據(jù)最終用戶(hù)將看到的內(nèi)容來(lái)劃分產(chǎn)品模塊,讓每個(gè)微前端都封裝應(yīng)用的某個(gè)頁(yè)面,并分配給一個(gè)團(tuán)隊(duì)完整負(fù)責(zé)。相比圍繞技術(shù)或“橫向”問(wèn)題(如樣式、表單或驗(yàn)證)打造的團(tuán)隊(duì)相比,這種團(tuán)隊(duì)能有更高的凝聚力。

缺點(diǎn)

有得必有失,在引入微前端的過(guò)程中難免會(huì)引入一些新的問(wèn)題。只不過(guò)我們認(rèn)為這些風(fēng)險(xiǎn)都能控制在合理水平上,微前端終究還是利大于弊的。

重復(fù)依賴(lài)

不同應(yīng)用之間依賴(lài)的包存在很多重復(fù),由于各應(yīng)用獨(dú)立開(kāi)發(fā)、編譯和發(fā)布,難免會(huì)存在重復(fù)依賴(lài)的情況。導(dǎo)致不同應(yīng)用之間需要重復(fù)下載依賴(lài),額外再增加了流量和服務(wù)端壓力。

團(tuán)隊(duì)之間更加分裂

大幅提升的團(tuán)隊(duì)自治水平可能會(huì)讓各個(gè)團(tuán)隊(duì)的工作愈加分裂。各團(tuán)隊(duì)只關(guān)注自己的業(yè)務(wù)或者平臺(tái)功能,在面向用戶(hù)的整體交付方面,會(huì)導(dǎo)致對(duì)用戶(hù)需求和體現(xiàn)不敏感,和響應(yīng)不及時(shí)。

微前端應(yīng)用場(chǎng)景

兼容遺留系統(tǒng)

經(jīng)常會(huì)有團(tuán)隊(duì)需要在兼容已有系統(tǒng)的前提下,使用新框架去開(kāi)發(fā)新功能。遺留系統(tǒng)功能已經(jīng)完善,并且穩(wěn)定運(yùn)行,團(tuán)隊(duì)沒(méi)有必要,也沒(méi)有精力去將遺留系統(tǒng)重構(gòu)一遍。此時(shí)團(tuán)隊(duì)如果需要使用新框架,新技術(shù)去開(kāi)發(fā)新的應(yīng)用,使用微前端是很好的解決方案。

應(yīng)用聚合

大型互聯(lián)網(wǎng)公司都會(huì)為用戶(hù)提供很多應(yīng)用和服務(wù),如何為用戶(hù)呈現(xiàn)具有統(tǒng)一用戶(hù)體驗(yàn)的應(yīng)用聚合成為必須解決的問(wèn)題。而在大型商業(yè)公司內(nèi)部,往往部署有大量的軟件服務(wù)。如何為員工提供服務(wù)聚合,提供員工工作效率,成為企業(yè)內(nèi)部IT建設(shè)的重中之重。前端聚合已成為一個(gè)技術(shù)趨勢(shì),目前比較理想的解決方案就是微前端。

團(tuán)隊(duì)間共享

不用應(yīng)用之間往往存在很多可以共享和功能和服務(wù),如果在團(tuán)隊(duì)之間進(jìn)行高質(zhì)量的共享成為提高研發(fā)效率的一條重要途徑。微前端可以采用組件或者服務(wù)的方式進(jìn)行團(tuán)隊(duì)間的技術(shù)共享。其低內(nèi)聚高耦合的共享,使得高質(zhì)量的共享成為可能。

局部/增量升級(jí)

一個(gè)大的產(chǎn)品由很多應(yīng)用和服務(wù)組成,很多時(shí)候只需要對(duì)部分應(yīng)用和服務(wù)進(jìn)行升級(jí)。如果是單體應(yīng)用,升級(jí)耗時(shí)長(zhǎng),風(fēng)險(xiǎn)高,影響可服務(wù)性。而前端可以只對(duì)需要的應(yīng)用和服務(wù)進(jìn)行升級(jí),不會(huì)影響其他應(yīng)用和服務(wù)。升級(jí)效率高,風(fēng)險(xiǎn)低,不影響其他應(yīng)用和服務(wù)的可服務(wù)性。

微前端要克服的幾個(gè)障礙

既然微前端具有如此多的優(yōu)點(diǎn),您是不是已經(jīng)躍躍欲試,想要馬上在團(tuán)隊(duì)里引入了呢?且慢,在引入微前端的過(guò)程中會(huì)遇到一些障礙,我們先看看會(huì)遇到那些障礙吧。

資源的隔離

由于存在不同應(yīng)用各自定義CSS和全局變量的情況,應(yīng)用聚合時(shí)需要考慮彼此之間的影響。應(yīng)用JS沙箱和CSS隔離等相關(guān)技術(shù),使各應(yīng)用之間互不影響。

應(yīng)用的注冊(cè)

Html Entry 和 Config Entry,是關(guān)于如何注冊(cè)子應(yīng)用信息。

對(duì)性能的影響

按需加載、公共依賴(lài)加載和預(yù)加載,是關(guān)于性能的,這些很重要,否則雖然上了微前端,但性能?chē)?yán)重下降,或者由于升級(jí)引起線上故障,就得不償失了。

應(yīng)用間通信

父子應(yīng)用通訊,顧名思義,無(wú)需解釋。

應(yīng)用嵌套/并行

子應(yīng)用嵌套 和 子應(yīng)用并行 是微前端的進(jìn)階應(yīng)用,在某些場(chǎng)景下會(huì)用到。

微前端實(shí)現(xiàn)的幾種方式

路由分發(fā)式微前端

路由分發(fā)式微前端,即通過(guò)路由將不同的業(yè)務(wù)分發(fā)到不同的、獨(dú)立前端應(yīng)用上。其通??梢酝ㄟ^(guò) HTTP 服務(wù)器的反向代理來(lái)實(shí)現(xiàn),又或者是應(yīng)用框架自帶的路由來(lái)解決。
目前,通過(guò)路由分發(fā)式的微前端架構(gòu)應(yīng)該是采用最多、最容易實(shí)現(xiàn)的 “微前端” 方案。但這種方式實(shí)際上只是多個(gè)前端應(yīng)用的聚合并不是一個(gè)完整的整體。每次用戶(hù)從A應(yīng)用跳轉(zhuǎn)到B應(yīng)用的時(shí)候,實(shí)際上是訪問(wèn)不同的html頁(yè)面。
它適用于以下場(chǎng)景:

  • 不同技術(shù)棧之間差異比較大,難以兼容、遷移、改造
  • 項(xiàng)目不想花費(fèi)大量的時(shí)間在這個(gè)系統(tǒng)的改造上
  • 現(xiàn)有的系統(tǒng)在未來(lái)將會(huì)被取代
  • 系統(tǒng)功能已經(jīng)很完善,基本不會(huì)有新需求

使用iFrame創(chuàng)建容器

使用iframe標(biāo)簽嵌套將另一個(gè)HTML頁(yè)面嵌入到當(dāng)前頁(yè)面中。iframe可以創(chuàng)建一個(gè)全新的獨(dú)立的宿主環(huán)境,這意味著我們的前端應(yīng)用之間可以相互獨(dú)立運(yùn)行。采用iframe有幾個(gè)重要的前提:

  • 網(wǎng)站不需要 SEO 支持
  • 擁有相應(yīng)的應(yīng)用管理機(jī)制。

在采用iframe的時(shí)候,我們需要做這么兩件事:

  • 設(shè)計(jì)管理應(yīng)用機(jī)制:在什么情況下,我們會(huì)去加載、卸載這些應(yīng)用;在這個(gè)過(guò)程中,采用怎樣的動(dòng)畫(huà)過(guò)渡,讓用戶(hù)看起來(lái)更加自然。
  • 設(shè)計(jì)應(yīng)用通訊機(jī)制:直接在每個(gè)應(yīng)用中創(chuàng)建 postMessage 事件并監(jiān)聽(tīng),并不是一個(gè)友好的事情。其本身對(duì)于應(yīng)用的侵入性太強(qiáng),因此通過(guò) iframeEl.contentWindow去獲取iFrame容器內(nèi)的Window對(duì)象是一個(gè)更簡(jiǎn)化的做法。隨后,就需要定義一套通訊規(guī)范:事件名采用什么格式、什么時(shí)候開(kāi)始監(jiān)聽(tīng)事件等等。

自制框架兼容應(yīng)用

不論是基于Web Components的Angular,或者是VirtualDOM的React 等,現(xiàn)有的前端框架都離不開(kāi)基本的HTML元素DOM。
那么,我們只需要:

  • 在頁(yè)面合適的地方引入或者創(chuàng)建 DOM
  • 用戶(hù)操作時(shí),加載對(duì)應(yīng)的應(yīng)用(觸發(fā)應(yīng)用的啟動(dòng)),并能卸載應(yīng)用。

第一個(gè)問(wèn)題,創(chuàng)建 DOM 是一個(gè)容易解決的問(wèn)題。而第二個(gè)問(wèn)題,則一點(diǎn)兒不容易,特別是移除 DOM 和相應(yīng)應(yīng)用的監(jiān)聽(tīng)。當(dāng)我們擁有一個(gè)不同的技術(shù)棧時(shí),我們就需要有針對(duì)性設(shè)計(jì)出一套這樣的邏輯。

盡管Single-SPA已經(jīng)擁有了大部分框架(如 React、Angular、Vue 等)的啟動(dòng)和卸載處理,但是它仍然適合于微前端的加載和卸載。可以自己設(shè)計(jì)和實(shí)現(xiàn)一個(gè)微前端框架。雖然,這種方式的上手難度相對(duì)比較高,但是后期訂制及可維護(hù)性比較方便。在不考慮每次加載應(yīng)用帶來(lái)的用戶(hù)體驗(yàn)問(wèn)題,其唯一存在的風(fēng)險(xiǎn)可能是:第三方庫(kù)不兼容。
但是,不論怎樣,與iFrame相比,其在技術(shù)上更先進(jìn)。同時(shí)與iframe類(lèi)似,我們?nèi)匀幻鎸?duì)著一系列的不大不小的問(wèn)題:

  • 需要設(shè)計(jì)一套管理應(yīng)用的機(jī)制。
  • 對(duì)于流量大的toC應(yīng)用來(lái)說(shuō),會(huì)在首次加載的時(shí)候,會(huì)多出大量的請(qǐng)求。

組合式集成:將應(yīng)用微件化

組合式集成,即通過(guò)軟件工程的方式在構(gòu)建前、構(gòu)建時(shí)、構(gòu)建后等步驟中,對(duì)應(yīng)用進(jìn)行一步的拆分,并重新組合。

從這種定義上來(lái)看,它可能算不上并不是一種微前端——它可以滿(mǎn)足了微前端的三個(gè)要素,即:獨(dú)立運(yùn)行、獨(dú)立開(kāi)發(fā)、獨(dú)立部署。但是,配合上前端框架的組件 Lazyload 功能——即在需要的時(shí)候,才加載對(duì)應(yīng)的業(yè)務(wù)組件或應(yīng)用,它看上去就是一個(gè)微前端應(yīng)用。與此同時(shí),由于所有的依賴(lài)、Pollyfill已經(jīng)盡可能地在首次加載了,CSS樣式也不需要重復(fù)加載。

常見(jiàn)的方式有:

  • 獨(dú)立構(gòu)建組件和應(yīng)用,生成 chunk 文件,構(gòu)建后再歸類(lèi)生成的 chunk 文件。(這種方式更類(lèi)似于微服務(wù),但是成本更高)
  • 開(kāi)發(fā)時(shí)獨(dú)立開(kāi)發(fā)組件或應(yīng)用,集成時(shí)合并組件和應(yīng)用,最后生成單體的應(yīng)用。
  • 在運(yùn)行時(shí),加載應(yīng)用的 Runtime,隨后加載對(duì)應(yīng)的應(yīng)用代碼和模板。

應(yīng)用間的關(guān)系如下圖所示:


weijian.jpg

組合式集成對(duì)比

這種方式看上去相當(dāng)?shù)睦硐?,即能滿(mǎn)足多個(gè)團(tuán)隊(duì)并行開(kāi)發(fā),又能構(gòu)建出適合的交付物。

但是,首先它有一個(gè)嚴(yán)重的限制:必須使用同一個(gè)框架。對(duì)于多數(shù)團(tuán)隊(duì)來(lái)說(shuō),這并不是問(wèn)題。采用微服務(wù)的團(tuán)隊(duì)里,也不會(huì)因?yàn)槲⒎?wù)這一個(gè)前端,來(lái)使用不同的語(yǔ)言和技術(shù)來(lái)開(kāi)發(fā)。當(dāng)然了,如果要使用別的框架,也不是問(wèn)題,我們只需要結(jié)合上一步中的自制框架兼容應(yīng)用就可以滿(mǎn)足我們的需求。

其次,采用這種方式還有一個(gè)限制,那就是:規(guī)范!在采用這種方案時(shí),我們需要:

  • 統(tǒng)一依賴(lài)。統(tǒng)一這些依賴(lài)的版本,引入新的依賴(lài)時(shí)都需要一一加入。
    規(guī)范應(yīng)用的組件及路由。避免不同的應(yīng)用之間,因?yàn)檫@些組件名稱(chēng)發(fā)生沖突。
  • 構(gòu)建復(fù)雜。在有些方案里,我們需要修改構(gòu)建系統(tǒng),有些方案里則需要復(fù)雜的架構(gòu)腳本。
  • 共享通用代碼。
  • 制定代碼規(guī)范。
    因此,這種方式看起來(lái)更像是一個(gè)軟件工程問(wèn)題。

純Web Components技術(shù)構(gòu)建

Web Components是一套不同的技術(shù),允許您創(chuàng)建可重用的定制元素(它們的功能封裝在您的代碼之外)并且在您的 Web 應(yīng)用中使用它們。

它主要由四項(xiàng)技術(shù)組件:

  • Custom elements,允許開(kāi)發(fā)者創(chuàng)建自定義的元素。
  • Shadow DOM,即影子 DOM,通常是將 Shadow DOM 附加到主文檔 DOM 中,并可以控制其關(guān)聯(lián)的功能。而這個(gè) Shadow DOM 則是不能直接用其它主文檔 DOM 來(lái)控制的。
  • HTML templates,即template和slot元素,用于編寫(xiě)不在頁(yè)面中顯示的標(biāo)記模板。
  • HTML Imports,用于引入自定義組件。
    每個(gè)組件由 link 標(biāo)簽引入:
<link rel="import" href="components/di-li.html">
<link rel="import" href="components/d-header.html">

隨后,在各自的 HTML 文件里,創(chuàng)建相應(yīng)的組件元素,編寫(xiě)相應(yīng)的組件邏輯。一個(gè)典型的Web Components應(yīng)用架構(gòu)如下圖所示:


image

Web Components 架構(gòu)

可以看到這邊方式與我們上面使用iframe的方式很相似,組件擁有自己獨(dú)立的 Scripts 和 Styles,以及對(duì)應(yīng)的用于單獨(dú)部署組件的域名。然而它并沒(méi)有想象中的那么美好,要直接使用純Web Components來(lái)構(gòu)建前端應(yīng)用的難度有:

  • 重寫(xiě)現(xiàn)有的前端應(yīng)用。我們需要使用Web Components來(lái)完成整個(gè)系統(tǒng)的功能。
  • 上下游生態(tài)系統(tǒng)不完善。缺乏相應(yīng)的一些第三方控件支持,這也是為什么jQuery相當(dāng)流行的原因。
  • 系統(tǒng)架構(gòu)復(fù)雜。當(dāng)應(yīng)用被拆分為一個(gè)又一個(gè)的組件時(shí),組件間的通訊就成了一個(gè)特別大的麻煩。

Web Components中的Shadow DOM更像是新一代的前端DOM容器,遺憾的是并不是所有的瀏覽器,都可以完全支持Web Components。

結(jié)合Web Components構(gòu)建

Web Components離現(xiàn)在的我們太遠(yuǎn),可是結(jié)合Web Components來(lái)構(gòu)建前端應(yīng)用,則更是一種面向未來(lái)演進(jìn)的架構(gòu)?;蛘哒f(shuō)在未來(lái)的時(shí)候,我們可以開(kāi)始采用這種方式來(lái)構(gòu)建我們的應(yīng)用。好在,已經(jīng)有框架在打造這種可能性。

就當(dāng)前而言,有兩種方式可以結(jié)合Web Components來(lái)構(gòu)建微前端應(yīng)用:

  • 使用Web Components構(gòu)建獨(dú)立于框架的組件,隨后在對(duì)應(yīng)的框架中引入這些組件
  • 在Web Components中引入現(xiàn)有的框架,類(lèi)似于iframe的形式
    前者是一種組件式的方式,或者則像是在遷移未來(lái)的 “遺留系統(tǒng)” 到未來(lái)的架構(gòu)上。

在Web Components中集成現(xiàn)有框架

現(xiàn)有的Web框架已經(jīng)有一些可以支持Web Components的形式,諸如 Angular支持的createCustomElement,就可以實(shí)現(xiàn)一個(gè)Web Components形式的組件:

platformBrowser()
  .bootstrapModuleFactory(MyPopupModuleNgFactory)
    .then(({injector}) => {
      const MyPopupElement = createCustomElement(MyPopup, {injector});
      customElements.define(‘my-popup’, MyPopupElement);
});

在未來(lái),將有更多的框架可以使用類(lèi)似這樣的形式,集成到Web Components應(yīng)用中。

集成在現(xiàn)有框架中的 Web Components

另外一種方式,則是類(lèi)似于Stencil的形式,將組件直接構(gòu)建成Web Components形式的組件,隨后在對(duì)應(yīng)的諸如,如 React 或者 Angular 中直接引用。

如下是一個(gè)在 React 中引用 Stencil 生成的Web Components的例子:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';

import 'test-components/testcomponents';

ReactDOM.render(<App />, document.getElementById('root'));
registerServiceWorker();

在這種情況之下,我們就可以構(gòu)建出獨(dú)立于框架的組件。

同樣的 Stencil 仍然也只是支持最近的一些瀏覽器,比如:Chrome、Safari、Firefox、Edge 和 IE11

復(fù)合型

復(fù)合型,就是針對(duì)實(shí)際的應(yīng)用場(chǎng)景,選取上面的幾個(gè)類(lèi)型挑幾種組合起來(lái)解決實(shí)際問(wèn)題。

微前端架構(gòu)選型指南

那么如何依據(jù)不同的情況來(lái)選擇合適的方案呢。
快速選型指南圖:


image

微前端選型指南

關(guān)鍵點(diǎn)的相關(guān)解釋如下:

  • 框架限制: 在現(xiàn)實(shí)中多數(shù)組織需要兼容遺留系統(tǒng),在技術(shù)選型上會(huì)有這樣那樣的限制。

  • IE問(wèn)題: 不論是在幾年前,還是在今年,我們實(shí)施微前端最先考慮的就是對(duì)于IE的支持。在我遇到的項(xiàng)目上,基本上都需要支持IE,因此在技術(shù)選型上就受限一定的限制。而在我們那些不需要支持IE的項(xiàng)目上,他們就可以使用Web Components技術(shù)來(lái)構(gòu)建微前端應(yīng)用。

  • 依賴(lài)獨(dú)立: 即各個(gè)微前端應(yīng)用的依賴(lài)是要統(tǒng)一管理,還是要在各個(gè)應(yīng)該中自己管理。統(tǒng)一管理可以解決重復(fù)加載依賴(lài)的問(wèn)題,獨(dú)立管理會(huì)帶來(lái)額外的流量開(kāi)銷(xiāo)和等待時(shí)間。

微前端方案的對(duì)比:

方式 開(kāi)發(fā)成本 維護(hù)成本 可行性 同一框架要求 實(shí)現(xiàn)難度 潛在風(fēng)險(xiǎn)
路由分發(fā) 這個(gè)方案太普通了
iFrame 這個(gè)方案太普通了
應(yīng)用微服務(wù)化 ★★★★ 針對(duì)每個(gè)框架做定制及 Hook
微件化 ★★★★★ 針對(duì)構(gòu)建系統(tǒng),如 webpack 進(jìn)行 hack
微應(yīng)用化 ★★★ 統(tǒng)一不同應(yīng)用的構(gòu)建規(guī)范
純 Web Components ★★ 新技術(shù),瀏覽器的兼容問(wèn)題
結(jié)合 Web Components ★★ 新技術(shù),瀏覽器的兼容問(wèn)題

同樣的,一些復(fù)雜概念的解釋如下:

應(yīng)用微服務(wù)化,即每個(gè)前端應(yīng)用一個(gè)獨(dú)立的服務(wù)化前端應(yīng)用,并配套一套統(tǒng)一的應(yīng)用管理和啟動(dòng)機(jī)制,諸如微前端框架 Single-SPA 或者 mooa 。

微件化,即通過(guò)對(duì)構(gòu)建系統(tǒng)的 hack,使不同的前端應(yīng)用可以使用同一套依賴(lài)。它在應(yīng)用微服務(wù)化的基本上,改進(jìn)了重復(fù)加載依賴(lài)文件的問(wèn)題。

微應(yīng)用化,又可以稱(chēng)之為組合式集成,即通過(guò)軟件工程的方式,在開(kāi)發(fā)環(huán)境對(duì)單體應(yīng)用進(jìn)行拆分,在構(gòu)建環(huán)境將應(yīng)用組合在一起構(gòu)建成一個(gè)應(yīng)用。詳細(xì)的細(xì)節(jié),可以期待后面的文章《一個(gè)單體前端應(yīng)用的拆解與微服務(wù)化》

微前端方案的對(duì)比:復(fù)雜方式
之前看到一篇微服務(wù)相關(guān)的 文章,介紹了不同微服務(wù)的區(qū)別,其采用了一種比較有意思的對(duì)比方式特別詳細(xì),這里就使用同樣的方式來(lái)展示:

架構(gòu)目標(biāo) 描述
a. 獨(dú)立開(kāi)發(fā) 獨(dú)立開(kāi)發(fā),而不受影響
b. 獨(dú)立部署 能作為一個(gè)服務(wù)來(lái)單獨(dú)部署
c. 支持不同框架 可以同時(shí)使用不同的框架,如 Angular、Vue、React
d. 搖樹(shù)優(yōu)化 能消除未使用的代碼
e. 環(huán)境隔離 應(yīng)用間的上下文不受干擾
f. 多個(gè)應(yīng)用同時(shí)運(yùn)行 不同應(yīng)用可以同時(shí)運(yùn)行
g. 共用依賴(lài) 不同應(yīng)用是否共用底層依賴(lài)庫(kù)
h. 依賴(lài)沖突 依賴(lài)的不同版本是否導(dǎo)致沖突
i. 集成編譯 應(yīng)用最后被編譯成一個(gè)整體,而不是分開(kāi)構(gòu)建

那么,對(duì)于下表而言,表中的 a~j 分別表示上面的幾種不同的架構(gòu)考慮因素。

方式 a b c d e f g h i
路由分發(fā) O O O O O O
iFrame O O O O O O
應(yīng)用微服務(wù)化 O O O O
微件化 O O - - O -
微應(yīng)用化 O O O - - O - O
純Web Components O O O O O - - O
結(jié)合Web Components O O O O O O O

圖中的 O 表示支持,空白表示不支持,- 表示不受影響。

微前端的業(yè)務(wù)拆分

  • 按照業(yè)務(wù)拆分
  • 按照權(quán)限拆分
  • 按照變更頻率拆分
  • 按照組織結(jié)構(gòu)拆分
  • 跟隨后端微服務(wù)拆分

這些分類(lèi)方法,直接看字面應(yīng)該不會(huì)有歧義了,如何選擇,就要看實(shí)際情況了

微前端框架介紹

https://github.com/CanopyTax/single-spa
https://github.com/ionic-team/stencil
https://github.com/phodal/mooa

參考資料

書(shū)籍
《前端架構(gòu):從入門(mén)到微前端》
文章
《干貨分享:螞蟻金服前端框架和工程化實(shí)踐》
《大前端時(shí)代下的微前端架構(gòu):實(shí)現(xiàn)增量升級(jí)、代碼解耦、獨(dú)立部署》
《用微前端的方式搭建類(lèi)單頁(yè)應(yīng)用(美團(tuán)微前端方案)》
《微前端的設(shè)計(jì)理念與實(shí)踐初探》
《微前端的那些事兒》
《微前端如何落地》

?著作權(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)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 完整版文章請(qǐng)?jiān)L問(wèn)我的個(gè)人博客查看:damienzhong.com 微服務(wù) “微服務(wù)架構(gòu)(Microservice ...
    呆萌鐘閱讀 811評(píng)論 0 2
  • 蒼綠桂道,匆匆過(guò)了多少南方姑娘的身影 青蔥如她,何須粉黛,已然醉了誰(shuí)? 紅色的葉子,我想起她揚(yáng)起的笑 金色的霓裳,...
    山有木希閱讀 592評(píng)論 9 15
  • 記得初次見(jiàn)他,是一個(gè)一閃一閃亮晶晶,滿(mǎn)天都是小星星的夏天的晚上,電視機(jī)里播放著扣人心弦的《大耳朵圖圖》,聚精會(huì)神的...
    風(fēng)車(chē)wks閱讀 992評(píng)論 1 6
  • 黃鈺芹: 黃金反復(fù)震蕩,為何你總是虧損? 現(xiàn)貨黃金反復(fù)震蕩為何你總是虧損?交易5個(gè)階段詳解; 面對(duì)虧損,雖是很多朋...
    黃鈺芹閱讀 184評(píng)論 0 0
  • 上次提到的一些瘦身的飲食原則還是比較常見(jiàn)的,實(shí)際上,小編還有些許鮮為人知的高招等著你去體會(huì),掌握了這些飲食方法,想...
    朵小陽(yáng)閱讀 419評(píng)論 0 0

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