基於下一代構建方案落地JOYY業務中臺微前端

背景

目前通過一系列調研,大致總結出主流微前端方案大致分爲前端

  • 基座模式:經過搭建基座、配置中心來管理子應用
    • 統一框架約定方案《微前端在美團外賣的實踐背景》
      • 統一業務框架 REACT
      • 統一配置信息
      • 創建基座工程,用於管理子工程的路由切換、註冊子工程的路由和全局Store層、提供全局庫和複用層
    • 問題點
      • 經過中心化配置的方式註冊到基座工程進行加載
      • 項目改造存在必定成本
      • 代碼複用性以及子應用調用的易用性存在疑慮
    • 多框架並存方案Single-spa
      • 多框架並存、而且實現互不干擾
      • 建立根應用程序,以動態模塊加載的方式加載子應用。
      • 獨立發佈的子應用提供一個活動 url 資源地址,隨後在根應用中藉助模塊加載器(如 SystemJS)動態加載。
    • 問題點
      • 對於React 深度定製項目來講,沒法作到狀態管理很好的傳遞
      • 對於非標準的AMD、UMD、SystemJS 等加載方式的庫會存在依賴問題(須要針對性改造)
      • 多框架實現體積過大以及存在必定的調試成本
  • 自組織模式:經過約定進行互調
    • monorepo + npm包組合
    • amd,cmd or umd 等直接引用
    • webpack external
    • 問題點

思考

目前業務中臺在業務推動過程當中遇到比較多的問題是webpack

  • 如何更好的減小代碼冗餘
  • 如何更高效的提高開發效率
  • 如何減小通用資源更新所帶來的影響力度
  • 項目與項目之間如何更好下沉業務組件
  • 可複用庫與組件之間如何造成約定類型或者文檔,讓調用方更加高效完成任務,減小溝通成本

統一技術棧

從開發初期咱們約定了中臺的統一框架:React & hook + React-dom + React-router-dom + Mobx + Typescript,減小後期的額外框架消耗以及維護成本;
複用組件、工具庫之間使用lerna + monorepo 方式下沉項目組件,經過npm方式安裝到獨立業務git

從項目過程當中遇到形形式式的包管理問題,以及代碼重複打包,包信息更新不能及時等等問題github

嘗試使用 single-spa 落地微前端

  • 項目推動中期上微前端須要對項目源碼進行改造
  • 項目深度依賴mobx 進行狀態管理,依賴react-router-dom 作路由管理,在通用組件調用的同時不能用路由包裹傳遞
  • 依賴single-spa 對非 umd 調用庫支持不足須要進行必定改造

自組織模式

自組織模式:應用之間是平等的,不存在相互管理的模式。設計難度大,不方便實施,可是通用度高。
從目前主流開發模式下是很難完成 自組織模式的微前端落地,直到 Module Federation的出現web

方案設計

Module Federation 的特性中咱們挖掘出一套屬於業務中臺的設計模型

  • 組件聯邦機制方式代替中心化,無需基站以及配置中心介入
  • 以ts類型的方式進行約定
  • 統一React框架、讓組件中能夠深度定製與引用(無需更改原有業務代碼)
  • 創建完善腳手架和類型同步方案,讓開發部署獲得約束以及自動化完成

基站式微前端方案 VS EMP微前端方案

微前端對比

基站式微前端 EMP 微前端
路由 註冊機制+子項目自定義 項目自定義,無需註冊
支持多框架 支持 約定React框架(減小冗餘與維護成本)
複用組件引用 沙箱方式 可共享狀態組件方式
部署入口 基座 任何項目能夠做爲入口
Store 狀態共享 需改造 無需改造、無需註冊、直接調用
模塊調用 部分須要進行改造 直接調用
配置中心 約定入口 無(獨立入口或獨立組件支持,無需配置)
Typescript類型提示 沒法判斷 提供一站式類型判斷閉環
項目重構 須要根據約定重構 修改引用便可

EMP工做流

  • @efox/emp-cli 腳手架主要做用是
    • 調試
    • 構建、代碼分析
    • 生成項目所需類型
    • 經過遠程項目類型
  • @efox/emp-tune-dts-plugin ts相關類型操做
    • 1.在插件生命週期compiler.hooks.afterEmit.tap 執行生成類型文件
    • 2.類型文件生成後進行修正類型文件
  • @efox/emp-tsconfig 針對ts與微前端定製配置

用例代碼展現

antd + react-router-dom 爲例經過遠程方式引入外部定義好的骨架應用npm

//base->App.tsx
const App = ({layout, routes, stores}: RouterCompType) => (
    <StoreProvider stores={stores}> <RouterComp layout={layout} routes={routes || []} /> </StoreProvider> ) 複製代碼

當前應用引入外部庫bootstrap

//app->bootstrap.tsx
import EMPApp from '@emp-antd/base/App'
import stores from 'src/stores'
const App = () => <EMPApp routes={routes} stores={stores} />
複製代碼

遠程同步ts類型代碼提示antd

EMP基站設計模型

EMP基站主要做用是組織和共享通用庫,而非統一入口、統一配置react-router

EMP基站設計模型
EMP基站設計模型

說明

框架級基站(以框架/技術棧爲基礎,爲子基站提供框架級別的佈局,方法,組件)

  • 項目級基站(以業務項目爲基礎,爲項目提供業務組件,方法,路由,配置等)
    • 項目內容

優勢:

  1. 支持多框架並存,而且實現互不干擾
  2. 可根據項目級別定義多層級別基站
  3. 項目級別基站相對獨立
  4. 相同中臺基站下的項目可快速開發移植
  5. 項目間可共享獨立組件

EMP部署

多版本問題

在開發過程當中會遇到公共庫的不斷迭代以及項目使用的兼容性問題

  1. 基站部署:使用Docker的Volume方案,發佈前,經過自定義Dockerfile,將每一個版本內容都放在Volume中,而後從Volume拉取數據,最後進行發佈。
  2. Module Federationwebpack5 beta-17後支持定義版本,不一樣入口能夠應用能夠定製本身的引用庫版本如 React:16.13.1,而後從基站庫相應版本里調用相應的組件

域名規範

域名規範遵循 emp-antd-[業務名稱]-[環境].[一級域名].com。遵循這個規範,經過域名就能知道當前技術棧以及業務類型。

總結

從實戰過程當中已經能夠知足目前業務中臺的微前端需求,調用以及協同方面也獲得更好的推動

  • 一、從根本上擺脫了框架的束縛
  • 二、在最輕量級的基礎上進行微前端化,而且大量保留了原來代碼的業務邏輯
  • 三、最大化減小代碼的冗餘和更高的代碼複用
  • 四、落地應用不受入口限制,大大的提高了應用的定製如多主題等訴求

做者


Ken.Xu

D.Ragon

Abel

Benny Shi

Jiguli
相關文章
相關標籤/搜索