自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

生產(chǎn)可用:是時候來一個微前端架構了!

開發(fā) 架構
隨著前端越來越復雜,微前端的概念也越來越熱,那么什么是微前端?如何應用微前端來改進現(xiàn)有的前端架構?有沒有哪些成功的案例和實踐經(jīng)驗?

[[320741]]

 隨著前端越來越復雜,微前端的概念也越來越熱,那么什么是微前端?如何應用微前端來改進現(xiàn)有的前端架構?有沒有哪些成功的案例和實踐經(jīng)驗?

本文將分享微前端的場景域在螞蟻落地時遇到的問題,通過實施一個標準的微前端架構,提出面臨的技術決策以及需要處理的技術細節(jié),真正意義上幫助你構建一個生產(chǎn)可用的微前端架構系統(tǒng)。

微前端的場景域

在選擇一個微前端方案之前,常常需要思考這樣一個問題,我們?yōu)槭裁葱枰⑶岸恕Mǔξ⑶岸说脑V求有兩個方面,一是工程上的價值,二是產(chǎn)品上的價值。

對于工程上的價值,可以從一個三年陳的項目來看,如下所示, commit 的記錄顯示,第一次提交是 2016 年 8 月。

依賴樹 dependencies:

打包體積:

雖然這個三年陳的項目看上去版本比較低,但仍然是相對主流的全家桶方案。這樣一個樂觀的項目,在真實的場景中經(jīng)過三年的時間,也不實用了。因為開發(fā)的時間比較長,并且人員流動也比較大,會導致一些祖?zhèn)鞯拇a出現(xiàn),其次,在技術上不能及時的升級,導致開發(fā)體驗變得很差,例如打包的時間就超過三分鐘。也有可能在不經(jīng)意間依賴一些不兼容的框架,導致項目無法升級。種種原因,最后很有可能變成一個遺產(chǎn)項目。

對于產(chǎn)品體驗上的問題,例如下圖所示,要完成一個跳多個控制臺任務,在過程中發(fā)現(xiàn)每個控制臺視覺不統(tǒng)一、流程出現(xiàn)斷點以及重復加載或認證的問題導致整個產(chǎn)品的體驗較差。

微前端的定義

Techniques, strategies and recipes for building a modern web app with multiple teams using different JavaScript frameworks.

—— Micro Frontends。

以上是 Micro Frontends 網(wǎng)站對微前端的定義。意思是所謂微前端就是一種多個團隊之間可以使用不同技術構建一個現(xiàn)代化 web 的技術手段以及方法策略。其中的關鍵字是多團隊、采用不同的技術棧以及現(xiàn)代化的 web。微前端的思路繼承自微服務的思想。

微前端的架構圖

如圖,其中上層為統(tǒng)一共享的拼接層,主要做一些基礎信息的加載,和對來自不同團隊不同技術棧的客戶端在運行時動態(tài)組成一個完整的 SPA 應用,以及生命周期的調(diào)度和事件的管理??傊?,微前端是將微服務概念做了一個很好的延伸和實現(xiàn)。

在具體實踐中,衡量一個微前端方案是否是可利用的,需要滿足以下幾個條件:

  1. 技術棧無關性,不僅指子應用之間使用多個不同的框架,也指在使用同一個框架時,有可能在一個長的時間跨度下,由于框架的不兼容的升級,導致應用被鎖死的情況。
  2. 開發(fā)、發(fā)布及部署獨立,要求子應用和主應用做到工程上的解耦和獨立。
  3. 應用隔離的能力,是指需要考慮如何不干擾到原來子應用的開發(fā)模式和部署模式的情況下,做好運行時的樣式隔離、JS 隔離以及異常隔離等。

以上幾點是基于工程價值方面考慮的。此外,也需要動態(tài)組合的能力,是基于產(chǎn)品價值方面考慮的。

落地的關鍵問題

微前端架構中的技術選擇

按架構類型區(qū)分,常規(guī) web 應用的架構類型分為兩種,一種是 MPA,另一種是 SPA。如上圖所示為 2017 年各云產(chǎn)品控制臺架構調(diào)研,除了 google cloud 之外,大部分的云廠商都使用 MPA 架構。MPA 的優(yōu)點在于部署簡單,具備獨立開發(fā)和獨立部署的特性。但是,它的缺點是完成一個任務要跳到多個控制臺,并且每個控制臺又是重復刷新的。而 SPA 能極大保證多個任務之間串聯(lián)的流暢性,但問題是通常一個 SPA 是一個技術棧的應用,很難共存多個技術棧方案的選型。SPA 和 MPA 都是微前端方案的基礎選型,但是也都存在各自的問題。

單實例,一個運行時只有一個 APP Actived

多實例,一個運行同時有多個 APP Actived

按運行時特性區(qū)分,微前端包含兩個類別,一類是單實例,另一類是多實例。單實例場景如上圖中左側,通常是一個頁面級別的組合,例如一個運行時只有一個 App 被激活。多實例場景如上圖右側,像一個組件或者是容器級別的應用,運行時可以做到多個應用被同時激活。這兩種模式都有自己適應的場景和優(yōu)勢。微前端架構的核心訴求是實現(xiàn)能支持自由組合的微前端架構,將其他的 SPA 應用以及其他組件級別的應用自由的組合到平臺中。那么,如何選擇 SPA 和 MPA 以及單實例和多實例是一個問題,我們是否能探索出一種方案,將 SPA 和 MPA 工程上的特點結合起來,同時兼顧多實例和單實例運行時的場景來實現(xiàn)。

技術細節(jié)上的決策

為了實現(xiàn)上述的方案,在技術細節(jié)上的決策需要注意以下問題:

  1. 如何做到子應用之間的技術無關。
  2. 如何設計路由和應用導入。
  3. 如何做到應用隔離。
  4. 基礎應用之間資源的處理以及跨應用間通信的選擇。

對于如何做到子應用之間的技術無關問題,我們是通過協(xié)議來解決的。如下代碼所示的方式,就可以完成子應用的導入。如果子應用接入時做了一些框架上的耦合或者依賴一個具體實現(xiàn)庫的機制,就一定會存在與實現(xiàn)庫版本耦合的可能,不利于整個微前端生態(tài)的統(tǒng)一和融合。

  1. export async function bootstrap() { 
  2.   console.log('react app bootstraped') ; 
  3.  
  4. export async function mount(props) { 
  5.   console.log(props) ; 
  6.   ReactDOM.render(<App/>, document.getElementById('react15Root')); 
  7.  
  8. export async function unmount() { 
  9.   ReactDOM.unmountComponentAtNode(document.getElementById('react15Root') ) ; 

如下所示是一個與具體框架實現(xiàn)相耦合的例子(反例):

  1. //主應用 
  2. import React from 'react' ; 
  3. import ReactDOM from 'react-dom'
  4. import MicroFrontend from 'micro-frontend'
  5.  
  6. ReactDOM.render(<MicroFrontend  base="/app1" entry="//localhost/a.js">); 
  7.  
  8. //子應用 
  9. window.microFrontends = { 
  10.   app:{...} , 
  11.   reduxStore:{...} , 
  12.   globals:(...) , 

對于路由的問題,如下圖所示。這樣一條訪問鏈路后,刷新當前 URL 通常情況下會發(fā)生什么?

正常訪問一個站點,經(jīng)過一番操作之后,進入到站點的列表頁,路由會變大很復雜,但如果是一個微前端用戶,刷新一下頁面會出現(xiàn) 404 的情況。解決思路是將 404 路由 fallback 到一個異步注冊的子應用路由機制上。

對于應用導入方式的選擇,比較常見的方案是 Config Entry。通過在主應用中注冊子應用依賴哪些 JS。這種方案一目了然,但是最大的問題是 ConfigEntry 的方式很難描述出一個子應用真實的應用數(shù)據(jù)信息。真實的子應用會有一些 title 信息,依賴容器 ID 節(jié)點信息,渲染時會依賴節(jié)點做渲染,如果只配 JS 和 CSS,那么很多信息是會丟失的,有可能會導致間接上的依賴。

  1. <html> 
  2.   <head> 
  3.   <title>sub app</title> 
  4.     <link rel="stylesheet" href="//localhost/app.css"
  5. </head> 
  6. <body> 
  7.   <main id="root"></main> 
  8.    <script src="//localhost/base. js"
  9. </body> 
  10. </html> 
  11.  
  12. <script> 
  13.    import React from 'react' 
  14.    import ReactDOM from 'react-dom' 
  15.  
  16.    ReactDOM.render(<App/>, document.getElementById('root') ) 
  17. </script> 

 

 

 

 

 

 

另外一種方案是 HTML Entry,直接配 html,因為 html 本身就是一個完整的應用的 manifest,包含依賴的信息。HTML Entry 的優(yōu)點是接入應用的信息可以得到完整的保留,接入應用地址只需配一次,子應用的原始開發(fā)模式得到完整保留,因為子應用接入只需要告知主應用 html 在哪,包括在不接入主應用時獨立的打開。它的缺點是將解析的消耗留給了運行時。而 Config Entry 相較于 HTML Entry 減少了運行時的解析消耗。Config Entry 的缺點是主應用需配置完整的子應用信息,包含初始 DOM 信息、js/css 資源地址等。

  1. registerMicroApps([ 
  2.     { 
  3.         name'react app' 
  4.         //   index.html 本身就是一個完整的應用的 manifest 
  5.        entry: '//localhost: 8080/index.html'
  6.        render, 
  7.        activeRule: '/react' 
  8.      } 
  9. ]) ; 

對于樣式隔離問題,例如 BEM,每個子應用在寫樣式之前要加一些前綴,做一些隔離,但是這個做法并不推薦。相對而言,CSS Module 更簡單高效,也更智能化,是比較推薦的方式,但是也存在著問題。而 Web Components 看上去很不錯,但在實踐過程中也會發(fā)生一些問題。

例如在 Web Components 渲染的流程中出現(xiàn)了問題,如下圖所示。

在 antd 中提供了全局的 API,可以提前設置好所有的彈框的 container,但是也不是每個組件庫都能像 antd 一樣完成度那么高。

螞蟻所采用的解決方案是做動態(tài)的加載和卸載樣式表,如下圖所示,這種方案是很有效的。

對于 JS 隔離,螞蟻提出了 JS Sandbox 機制,如上圖所示,其中 bootstrap、mount及 unmount 生命周期是子應用需要暴露出來的,因為子應用的整個生命周期都是被主應用所管理的,所以可以在主應用中給子應用插入各種攔截的機制,也可以捕獲到子應用在加載期間做了哪些全局上的修改。在 unmount 時,可以將全局上的副作用全部手動移除掉,同時也可以實現(xiàn)在重新進來時,將上次忘記卸載的副作用重建一遍,因為需要保證下次進來時能完整回復到與上次一致的上下文。

對于資源加載問題,在微前端方案中存在一個典型的問題,如果子應用比較多,就會存在之間重復依賴的場景。解決方案是在主應用中主動的依賴基礎框架,然后子應用保守的將基礎的依賴處理掉,但是,這個機制里存在一個問題,如果子應用中既有 react 15 又有 react 16,這時主應用該如何做?螞蟻的方案是在主應用中維護一個語義化版本的映射表,在運行時分析當前的子應用,最后可以決定真實運行時真正的消費到哪一個基礎框架的版本,可以實現(xiàn)真正運行時的依賴系統(tǒng),也能解決子應用多版本共存時依賴去從的問題,能確保最大程度的依賴復用。

基于 props 以單向數(shù)據(jù)流的方式傳遞給子應用:

  1. export function mount(props) { 
  2.     ReactDOM.render( 
  3.         <App {...props}/>, 
  4.          container 
  5.     ) 

基于瀏覽器原生事件做通信:

  1. //主應用 
  2. window.dispathEvent( 
  3.     new CustomEvent('master:collapse-menu'), 
  4.     {detail: {collapsed:true} } 
  5.  
  6. //子應用 
  7. window.addEventLister( 
  8.     'master:collapse-menu'
  9.     event => console.log(event.detail.collapsed) 

對于應用之間數(shù)據(jù)共享及通信的問題,螞蟻提出了兩個原則,第一個原則是基于 props 以單向數(shù)據(jù)流的方式傳遞給子應用。第二個原則是基于瀏覽器原生事件做跨業(yè)務之間的通信。

在真實的生產(chǎn)實踐中,螞蟻總結出了幾點經(jīng)驗及建議:兄弟節(jié)點間通信以主應用作為消息總線,不建議自己封裝的 Pub/Sub 機制,也不推薦直接基于某一狀態(tài)管理庫做數(shù)據(jù)通信。

螞蟻在實踐中做的性能優(yōu)化,包括異步樣式導致閃爍問題的解決以及預加載問題的解決。

異步樣式導致的閃爍問題:

預加載:

  1. export function prefetch(entry: Entry, fetch?: Fetch) { 
  2.     const requestIdleCallback = window.requestIdleCallback || noop; 
  3.  
  4.     requestIdleCallback(async () => { 
  5.         const { getExternalScripts, getExternalStyleSheets } 
  6.             = await importEntry(entry, { fetch } ); 
  7.         requestIdleCallback(getExternalStyleSheets) ; 
  8.         requestIdleCallback(getExternalScripts) ; 
  9.     }) ; 

如圖所示為微前端方案涉及到的技術點,本文分享了圖中三分之二的內(nèi)容。

在螞蟻金服做了大量關于微前端方案之后,總結了衡量一個微前端方案是否友好的兩個標準,第一個標準是技術無關,也是微前端最核心的特性,不論是子應用還是主應用都應該做到框架不感知。第二個標準是接入友好,子應用接入應該像接入一個 iframe 一樣輕松自然。

螞蟻的微前端落地的實踐成果

螞蟻內(nèi)部基于微前端基礎架構提出了一體化上云解決方案,稱為 OneX,是一個基礎的平臺,它可以將各種流程和工具串聯(lián),其價值體現(xiàn)在品牌、產(chǎn)品和技術方面。品牌價值指的是統(tǒng)一的界面框架、UI、交互形成了螞蟻金服科技品牌心智。

OneNav + OneConsole + TechUI + OneAPI + Bigfish

下圖所示為螞蟻的一個真實應用的例子,除了中間接入的產(chǎn)品是自己控制之外,其他內(nèi)容都是由平臺提供,這樣,如論是一個三年陳項目還是新做的項目,在基本的視覺上可以做到統(tǒng)一。

產(chǎn)品價值指的是產(chǎn)品具有自由組合能力。之前的產(chǎn)品是多個產(chǎn)品、多個站點的控制臺,而現(xiàn)在只需要一個控制臺,將多個產(chǎn)品自由的組合,這樣,可以在商業(yè)上有更多的相應空間以及更多自由的搭配?;谶@樣的系統(tǒng)也可以做一些全局性的事情,例如埋點、用戶的轉(zhuǎn)化跟蹤業(yè)務。

技術價值指的是研發(fā)上的提效。經(jīng)過微前端的改造后,螞蟻可以將大型的系統(tǒng)解耦成可以獨立開發(fā)的并行的小型的系統(tǒng),這些小型系統(tǒng)可以交給別的團隊或者使用可視化的系統(tǒng)去實現(xiàn),最后在運行時只需要將他們集成起來。

在技術價值方面也可以實現(xiàn)交付上的提效,只需要在某一個環(huán)境的任意一個環(huán)境中做平臺上的接入,應用就可以做到在多余的環(huán)境中不改代碼,直接運行。

下圖為阿里云剛上市的一個產(chǎn)品例子,其中包括 15 個來自不同團隊的應用進行維護,它的特點是并不是單獨為阿里云而設計的,之前在螞蟻也有運行,只不過在阿里云中做了動態(tài)的組合。OneTour 微應用組件主要解決的是在多個產(chǎn)品控制臺之間自由切換導致流程割裂的問題。

螞蟻微前端的落地成果包括:有 70+ 線上應用接入(阿里云 + 螞蟻云 + 專有云),最復雜一個控制臺同時集成 15 個應用,并且有 4+ 不同技術棧,以及開發(fā)到發(fā)布上線全鏈路的自動化支持,一云入駐多云運行。

基于以上技術上的成果,螞蟻沉淀了自己的微前端方案并開源。

基于以上技術上的成果,螞蟻沉淀了自己的微前端方案并開源。qiankun 是框架無關的微前端內(nèi)核,umi-plugin-qiankun 是基于 umi 應用的 qiankun 插件,方便 umi 應用通過修改配置的方式變身成為一個微前端系統(tǒng)?;谏鲜鰧嵺`的檢驗和內(nèi)部落地結果來看,在大規(guī)模中后臺應用場景下,微前端架構是一個值得嘗試的方案。

 

責任編輯:武曉燕 來源: 阿里技術
相關推薦

2023-12-13 08:24:42

maven插件自動化

2020-05-19 10:45:31

沙箱前端原生對象

2012-08-23 11:03:55

IE瀏覽器

2023-11-01 18:10:45

架構設計技術

2022-05-31 08:35:05

RocketMQACK客戶端

2012-08-28 13:49:34

HTML5HTML5熱點關注HTML5業(yè)界資訊

2022-09-07 21:31:19

微前端架構iframe

2020-05-06 09:25:10

微前端qiankun架構

2018-05-30 10:04:38

容器技術微服務

2021-05-18 09:48:58

前端開發(fā)架構

2015-09-23 14:07:12

前端與后端架構實例

2021-06-24 09:53:05

前端架構開源

2014-02-17 17:47:16

前端后端架構

2022-05-13 11:05:00

網(wǎng)絡威脅無監(jiān)督學習網(wǎng)絡攻擊

2022-01-17 11:41:50

前端Vite組件

2023-02-13 00:18:22

前端庫框架集合

2023-10-19 15:25:40

2025-02-08 08:42:22

2022-09-27 08:19:20

前端React

2023-12-29 11:32:27

點贊
收藏

51CTO技術棧公眾號