美團外賣終端容器無關化研發框架

2019年9月,美團外賣技術團隊聯合多個研發部門正式推出了React2X,面向所有的前端研發人員,特別是按業務領域劃分的團隊,爲大家提供一個完整的、開放的多終端容器無關化(Containerless)研發框架。研發同學可以通過React2X框架快速創建、開發、構建、部署項目,在人力消耗最小的前提下,以期在不同終端上達到相對最佳的性能體驗,並且能大幅降低因容器升級帶來的替換和改造成本,讓代碼同構的複用率最大化。

終端容器無關化(Containerless):與服務無關化(Serverless)的概念類似,即在保持頂層業務研發語言不變更的情況下,在下層可以兼容性地升級、替換終端容器的能力,讓用戶無需關心終端容器的運維,只要將精力聚焦到業務邏輯上的技術。

一、前言

React2X是一款面向多終端、跨平臺、容器無關化研發框架。在整個美團前端技術棧日益規範的趨勢下,React技術棧在我們技術體系環節中的地位變得越來越重要。在廣告、營銷這些推廣屬性的業務上,在各個終端(包括美團App、美團外賣App、大衆點評App,以及站外的微信小程序、百度小程序、頭條&抖音小程序等其他終端)實現“一次開發,同步需求上線”的業務訴求也變得越來越多。在這樣的背景下,我們定義了React2X應用的核心場景:

  • 面對美團內部豐富多樣的技術容器體系(Mach、MRN、Titans、MTFlutter、MMP等),如何保證跨容器開發體驗的一致性,以及建設跨容器應用開發的生態能力,是我們需要解決的問題。
  • 公司內豐富的終端容器化技術蓬勃發展,而因業務升級帶來的改造成本也比較大,亟待一款高擴展性設計的頂層框架作爲技術抓手。
  • 跨容器動態化能力覆蓋,逐步成爲各個業務方越來越重視的基礎能力,可以大幅縮短需求交付的週期,提高上線發版的效率,並能有效地解決包體積大小的問題,提升業務的敏捷性
  • 多場景下的同構訴求,例如在各種推廣頁、模塊化、遊戲、輕量佈局差異的PC/App同構場景下,可以節省多端研發的人力。

最終我們的核心痛點圍繞在了美團系·小程序美團系·App矩陣上的同一個需求的多次開發運維上,爲了解決研發人力瓶頸問題,我們需要一款“一次研發,多終端容器複用”的研發框架來提升研發效率

調研整個前端領域,我們找到了一些業界的解決方案,像是美團最早的mpvue、騰訊的Wepy、滴滴的Chameleon、京東的Taro等等。在經過比較與試用之後,我們最終基於投入產出比的價值判斷,選擇站在巨人的肩膀上研發定製一款滿足美團技術、業務場景的研發框架——React2X(後面簡稱R2X)。從R2X第一個版本發佈到現在,已經接受了來自於公司各個業務兩年多的考驗。所以我們希望通過本文幫助大家對R2X有一個大致的瞭解。

二、目標與場景

2.1 核心目標

爲了解決業務需求在多端容器需要重複開發的難題,通過代碼複用實現開發提效,我們確定了以下的目標:

  • 解決公司內部多終端容器開發痛點:實現Webview容器、小程序容器、MRN容器、Mach容器、遊戲容器、部分運營推廣場景PC容器的代碼同構複用,統一開發規範,抹平開發差異,並提供對其他容器的擴展能力。
  • 建設跨容器動態化能力:跨容器動態化能力的缺失,導致產品不能夠通過快速迭代來驗證需求的效果,這個問題嚴重限制了業務的發展。跨容器動態化能力可以解決美團外賣業務端上發版和包體的問題,幫助業務實現快速發版上線、線上問題熱修復、以及容災的能力。
  • 建設容器無關的開發生態體系:R2X最終要解決的是容器差異性,進行統一的技術生態能力建設,爲多終端容器開發場景提升生產和運維效率。

2.2 應用場景

R2X開發框架主要期望能最終面向多終端應用的終端容器,用於場景化研發:

圖1

即:

  • 業務項目基於React語法爲技術框架基礎。
  • 業務方有在多終端/多容器(包括MRN容器、Webview容器、MP容器、Flutter容器、Mach容器、PC瀏覽器容器)運行的需求。
  • 業務方有特定的場景化訴求,包括推廣頁、模塊化、小遊戲、PC/App同構等等。

三、挑戰與優勢

3.1 業界調研

針對上述核心目標和應用場景,我們對市面上的跨容器框架進行了調研。由於美團外賣的技術棧統一是React爲主,所以我們的必備要求是:一款以React爲DSL語言的複用框架,能快速融入美團的技術生態。

根據下表的對比,如果以React爲DSL語言出發,當時就只有Taro一家能滿足我們的業務訴求,但它的生態環境並不適合在美團體系內使用。基於多方面因素的考慮,我們決定結合各大主流框架之所長,然後開發出一款屬於美團外賣的跨容器複用框架。

對比項 mpvue Taro 1.3 Chameleon WePY UniApp
DSL Vue 類React(Nerv) 類Vue Vue Vue
是否支持 React Native 是,但支持效果不佳 Weex
兼容 API 有(API支持程度不一) 自研多態協議
跨端組件庫
美團生態
語法校驗 ESLint 自研
TypeScript
定製化擴展 可自研Plugin
編譯擴展
調研結論 不匹配 部分滿足 部分滿足 不匹配 不匹配

注:前期調研時間截止到2019年05月,可能與當前數據存在一定的出入。

3.2 技術挑戰

當我們決定要打造一款屬於美團外賣的跨容器複用框架之後,在實現的過程中主要遇到了以下挑戰:

① 各個容器之間差異性適配成本

  • 語法語義:MRN/小程序/Webview在DSL上就有着完全不同的語法語義。
  • 端能力:同一容器在不同端上表現也存在不少差異,比如外賣App中MRN容器和美團App中MRN容器分別有定製的Native模塊以及各類橋協議等。

② 業務接入的使用成本

  • 首次成本:作爲一個新定義的框架如何讓新業務方快速上手,如何從存量業務線進行遷移。
  • 邊際成本:如何融合美團的基建生態,讓業務方快速複用平臺能力。

③ 頂層架構的合理設計

  • 高可維護性、高度擴展性:如何快速升級、替換、新增一款底層容器。

注:以上問題我們會在下文“技術全景”章節中給予解答。

3.3 項目優勢

3.3.1 功能特點對比

目前,業界以小程序作爲跨端目標平臺的框架較多,但大多都是使用Web前端技術棧作爲基礎,但同時兼顧React Native的技術棧就比較少。下表中列出的是支持以React、類React作爲DSL的相關框架進行對比。

R2X Taro 1.3 Taro 3.0 Rax Remax
原理 R2X 1.0重編譯時,R2X 2.0重運行時 重編譯時 重運行時 重運行時 重運行時
容器重點 以MRN,小程序,WebView爲主,同時支持MTFlutter、Mach、遊戲、PC瀏覽器 以小程序、Web爲主,React Native支持不多 以小程序、Web爲主,React Native交給58團隊支持 小程序、Web、Flutter 小程序、Web
API 支持KNB橋&對多平臺API進行了統一 對多平臺API進行了統一 對多平臺API進行了統一 多平臺不統一 多平臺不統一
跨端組件庫 有TaroUI,但不支持React Native 有TaroUI,但不支持React Native
業務組件擴展 提供擴展方案 參考TaroUI 參考TaroUI 提供擴展方案 提供擴展方案
美團內部生態支持 已支持埋點監控等
模塊化能力 支持 不支持 不支持 不支持 不支持
編譯插件擴展 支持 不支持 支持 支持 支持Webpack配置

綜上所述,從目前的業務形態來看,R2X在容器的匹配程度以及美團生態支持程度上看,是現階段的最佳方案。R2X相較於業界其他框架來說,擁有更加完善的適用於美團外賣團隊的本地化實現。

3.3.2 性能數據對比

基於業界跨平臺框架和美團內部的跨平臺框架,我們針對性能也進行了Benchmark測試,最終對比結果如下。

小程序性能對比

框架 創建 更新 添加 交換 刪除
R2X-MP 947.6 586.8 1467.2 1355.2 82.2
Remax 2798.2 1872.6 5162.2 4818.2 86.4
Taro-MP 1653.4 976.4 2483.2 2256.6 65.2

結論:可以看到,在小程序Benchmark測試結果中,R2X-MP是領先於Remax和Taro-MP。

與React Native性能對比

框架 創建 更新 添加 交換 刪除
R2X-MRN 309.875 83.75 384 191.875 82.125
MRN 297.625 105.25 400.125 231.625 65.875
Taro-RN 209.5 77.5 246.25 85.125 17.125

結論:在React Native的Benchmark測試結果中,R2X-MRN和MRN基本持平,但都低於純React Native的性能表現。

3.3.3 同構場景對比

除了支持了基本的React Native、小程序和Webview容器同構場景之外,R2X還實現了在MTFlutter、Mach、小遊戲(Webview遊戲、微信小遊戲&小程序、美團小遊戲)、PC瀏覽器等容器上的同構能力擴展,相比於業內的其他跨容器開發框架的生態也更加豐富和健全。

React Native 小程序 Webview Flutter 模塊級容器 小遊戲容器 PC瀏覽器(PC/App同構)
R2X 支持 支持 支持 支持 支持 支持 支持
Taro 支持 支持 支持 不支持 不支持 不支持 不支持
Rax 支持 支持 支持 不支持 不支持 不支持 不支持
Remax 支持 支持 支持 不支持 不支持 不支持 不支持

四、技術全景

圖2

上圖爲R2X的架構全景圖,整體架構可以按照從下到上,從左到右的視角進行解讀:

  • 最下層是R2X的生態環境建設,在R2X內部去實現公司生態的常用SDK以及業務中的各項專題能力;並通過搭建物料市場/插件市場,以業務共建的形式豐富R2X生態。
  • 再上層是R2XCore的根基,通過解析Command命令來執行喚起構建器,並實現了類似Webpack的插件系統,以插件化的形式組織驅動整個核心構建流程,便於維護以及擴展。
  • 再往上是跨端容器層,它是整個跨端能力的核心,通過實現了不同的容器插件來將R2X代碼編譯成各端可執行代碼,並通過運行時能力對組件/API進行對齊。
  • 最上層是承載的App端,目前有美團外賣、大衆點評、美團等多款移動App終端。
  • 最右邊是R2X在研發、發佈、運維以及用戶文檔上做的一些建設。

因爲R2X覆蓋了美團內部大部分的主流容器場景,所以技術體系較爲複雜和龐大,大家可以根據自身的業務形態,選擇性地去了解對應場景的同構方案。

4.1 底層基礎框架

4.1.1 R2X-CLI的設計

CLI作爲R2X項目驅動器,它不僅包含了命令行的啓動,更重要的,它是各個編譯構建的核心。

在早期,CLI執行build命令時,我們通過--type來區分不同的構建容器,從而加載不同的編譯邏輯。通過指定構建容器的形式來實現同一套代碼能夠構建出不同的容器產物。但經過長時間的業務迭代,我們發現了這種結構存在的問題:

  • 整體流程冗長且複雜,長時間迭代會變得越來越難以維護。
  • 每個容器的構建流程相互獨立,且構建邏輯各不一致,有多處重複的邏輯處理。
  • 編譯流程缺少統一的關鍵節點,編譯時無法進行業務方的定製擴展。

針對以上問題,我們考慮對CLI進行了一次全新的重構,引入插件化能力(關於插件化能力的具體實現會在下文詳細描述)。CLI整體結構變成如下圖所示:

圖3

整個CLI模塊只需要關心參數的解析以及插件的加載執行,不需要再實現各個容器的具體編譯邏輯。通過Hooks的形式,將編譯的各個時機暴露給插件,插件基於這些Hook進行編譯能力的實現,最終輸出產物給CLI模塊。這種形式帶來了以下幾個好處:

  • CLI結構變得清晰,只需要維護配置解析、插件解析等功能。
  • 擴展性增強,可通過插件化的形式新增或刪減容器/編譯能力,保證代碼獨立維護功能的單一性。
  • 編譯流程可梳理,無論什麼容器的編譯流程都基於編譯器暴露的時機執行並串聯,整體流程清晰明瞭。

4.1.2 組件及API的設計

R2X的目的是希望通過一套代碼能夠在多端上運行,但是由於多端差異的存在,我們需要設計一套統一的標準規範來進行對齊。在運行時部分,主要分爲組件/接口的對齊。

多端差異

在開始講述實現之前,我們先來看看各端之間的差異到底在哪些地方。

組件(標籤)差異

  • Webview標籤採用的是XML寫法,所提供的基礎標籤有<div/><a/>等等。
  • 小程序採用的是WXML(WeiXin Markup Language)標籤語言,也提供了一套完整的基礎標籤,但是和Webview有着較大的差異。
  • React Native則是採用的JSX(JS-XML)語法,雖然和XML很接近,但是又有着很多的不同點,同時它也有自己的一套基礎組件,和Webview、小程序又截然不同。

API差異

  • 接口差異:在不同端中都提供了相同或近似的功能,但是其實現方式以及調用參數可能存在着很大的差異,比如數據緩存Storage,小程序中用wx.setStorage/wx.setStorageSync,Webview則用localStorage.setItem,而MRN中AsyncStorage.setItem,幾乎每一個功能點都有着多多少少的差異。
  • 容器差異:各個端所提供的API都是各自的容器量身打造的,比如小程序的各業務接口類 API,完全是針對小程序所處的微信環境打造的,這類功能與其他端並不相關。
  • 能力差異:各個端之間的差異我們可以通過定製的手段來適配,然而並不是所有的功能點在各個端上都能夠實現。比如在Webview中就無法做到像小程序、React Native中提供很多原生能力,像是文件保存讀取等等,這一類差異性在適配過程中都屬於不可抗拒、不可抹平的差異。

樣式差異

小程序的WXSS和Webview的CSS在參數屬性上其實是幾乎一致的,但是在層級關係上有着很大的差別,小程序分爲全局樣式與局部樣式,各個組件之間的樣式也是不會相互影響(默認配置下)。而對比React Native採用的StyleSheet,是用Inline Style的方式,不支持全局樣式,不支持標籤樣式,並且屬性有諸多限制,如只能使用Flex佈局等等。

如何適配

從以上章節我們已經瞭解到了各個端之間有着非常大的差異點,那我們應該如何克服這些困難呢?

圖4

由於各端對組件和API的支持程度不同,我們選定了一端爲基礎標準,定義好各個組件的屬性以及接口參數,通過TypeScript的Interface進行實現。然後在各個端分別基於以上的接口進行功能對齊實現,對於端能力限制的功能進行了一定取捨,對高優功能進行了SDK底層實現適配。最終,我們基於已有的功能封裝實現了一套完整的基礎組件@r2x/components和基礎API@r2x/r2x

4.1.3 開放式插件能力

隨着R2X的在美團內部的應用越來越多,大家對於R2X模式的認可度也在不斷提高,我們從業務方中經常聽到以下這些問題:“是否可以增加支持某某功能/容器”,“我們業務架構比較特殊,能否做出一些調整”。業務方對R2X會有更多功能/容器的訴求,也會有更多定製化的需求出現。

所以,我們決定實現一套完整的開放式插件能力,提供一種相對比較簡單的方式,讓大家能夠自己來定製這些特殊需求。在最新的版本中,我們將R2X的編譯時進行了重構,在新的編譯時架構中引入了基於Tapable的插件系統。開發者可以通過編寫插件的方式爲R2X拓展更多功能,或者爲自身業務線定製更多的個性化功能。

在插件類型分爲兩類:

  • 容器插件,用於封裝R2X所支持的容器的核心編譯能力。
  • 功能插件,基於已有的容器插件,在此基礎上進行某種特定功能的自定義實現。

插件能力的整體架構如下:

圖5

藉助開發式插件能力,我們將之前編寫了若干個平臺容器插件,開發者安裝後即可使用:

  • 小程序容器插件:@r2x/plugin-container-wxapp。
  • MRN容器插件:@r2x/plugin-container-mrn。
  • Titans容器插件:@r2x/plugin-container-h5。

除了擴展新的容器平臺,我們還可以通過繼承現有的容器插件,來編寫一些特殊的定製化功能插件。

1. 對代碼進行預處理

基於開放式插件能力,我們可以像Babel插件一樣,通過對AST語法的修改對代碼源文件進行編譯前後的修改。比如:修改文件引用路徑、插入代碼片段、處理本地圖片等等。

2. 對文件產物進行修改

在編譯產出生成時,我們可以對編譯文件的內容、文件路徑、文件結構進行修改。結合自身業務的定製化,CLI可以將R2X項目和現有的原生項目進行結合改造。

除了以上功能,插件化能力爲用戶在編譯時提供了極大的自由度。如果你想體驗的話,歡迎加入美團外賣技術團隊。

4.1.4 特性能力-多態能力

爲什麼需要多態能力?

多態能力是用於提供跨端時各端組件及API的統一解決方案。基於多態能力,開發者可以定製自己的跨端組件。而R2X具備了完善的跨端能力,能夠覆蓋多終端和容器,爲什麼還需要多態?

業務研發爲了滿足各自場景的要求需要一定的靈活性。同時,Webview/小程序/React Native容器存在端上的差異,需要開發者人爲進行環境判斷。邏輯一複雜、跨端數量一多,代碼可讀性變低、維護成本起飛,這不是我們的本意。

基於這樣的背景,R2X提供了擴展性良好的多態能力。

R2X多態能力介紹

對於多態能力的支持,我們分爲兩類:

  • 多態組件/API,R2X根據文件後綴區分編譯目標端。

圖6

  • 差異化代碼,R2X提供getEnv環境方法用於判斷當前語句編譯目標端類型。
<View style={{color: R2X.getEnv() === "WEAPP" ? "green" : "blue" }} />

通過差異化代碼可輕鬆滿足端差異訴求。

4.2 應用場景同構

4.2.1 頁面級容器場景同構

頁面級容器場景同構我們借鑑了業內Taro1.x、Rax等優秀跨端框架的做法,結合美團內部容器、基建特點做了很多本地化實現和定製,在Webview、MRN、小程序三種容器上通過不同的編譯時方案進行預處理,並且引入了React運行時,保證了對React DSL支持的完整程度和代碼同構率,編譯時轉化流程方案和運行時結構如下圖所示:

圖7

R2X2.0相比於R2X1.0,運行時方案能夠解決編譯時方案帶來的語法限制問題:

  1. 不能在包含JSX元素的map循環中使用if表達式 ✅
  2. 不能使用Array#map之外的方法操作JSX數組 ✅
  3. 不能在JSX參數中使用匿名函數 ✅
  4. 暫不支持在render()之外的方法定義JSX ✅
  5. 不允許在JSX 參數(props)中傳入JSX元素 ✅
  6. 不能在JSX參數中使用對象展開符 ✅

同時也支持大部分React第三方生態庫,目前已支持使用原生react-redux。徹底抹平各端的差異,無論是MRN、Flutter、小程序、Webview的自定義組件都可以直接當成React組件引入,小程序原生自定義組件也無需配置usingComponents。

4.2.2 模塊級容器場景同構

在模塊級同構方案上,我們在App上依賴Mach容器;在小程序容器中,我們克服了Mach容器渲染機制的約束(運行時與虛擬DOM的使用限制),單獨在小程序上設計了Mach容器渲染方案,實現了R2X-模塊化(R2X-Module)在客戶端和小程序上99%以上的代碼同構率。

整體方案

圖8

  1. 核心驅動包,容器驅動的核心,針對渲染能力、解析能力、緩存能力、性能監控四個方面進行了實現,達到動態化驅動效果。
  2. 業務容器自定義,基於SDK提供的驅動能力,針對不同展位特性進行了容器自定義功能擴展配置,讓業務方可根據實際業務場景自行擴展。
  3. 分環境構建,主要實現了將類React語法進行AST編譯解析,根據構建平臺分別編譯成對應的Bundle產物。
  4. 自動化構建部署,將構建能力接入Talos(美團內部自研的構建部署工具),再結合低代碼業務工具實現一鍵部署,將編譯產物根據配置項上傳至DD(美團內部自研移動端動態下發平臺)。

模板驅動方案

目前,R2X-Module在客戶端和小程序容器的同構率在99.3%以上,在性能方面首次渲染時長和模板渲染時長的TP50時間分別是185ms144ms,比較優秀但還存在優化空間。同時提供R2X-Module SDK供業務方選擇。R2X-Module SDK初始化以及模板加載渲染流程如下圖所示:

圖9

4.2.3 PC/App適配同構

在移動互聯網發展已經高度成熟的今天,移動端的PV流量佔比絕大數,以外賣廣告商家端爲例,PC端僅僅佔有很少比例,其中PC流量佔比在我們部分業務上已經不及5%。因此在某些場景下實現PC/App的同構方案能夠解放一部分人力,對提高開發效率來說是十分必要的。目前,外賣廣告商家端的一些輕量佈局差異的頁面,已經完成了PC/App同構的方案設計和落地。

樣式同構適配

圖10

圖11

端能力擴展

R2X的基礎能力支持Webview/MRN/小程序三端,缺少對PC微前端子項目的支持。要實現PC/APP多端同構需要對R2X的端能力進行擴展。PC端本質上也屬於Web端,因此PC微前端的端能力擴展可以複用大部分的Webview的端能力。整體架構圖、技術設計要點、擴展流程圖如下所示:

圖12

平臺代碼處理

在項目同構開發中,不可避免地會出現跟平臺強相關的代碼或者業務邏輯,比如某些API調用的是App的底層能力,只能在React Native中使用,在Web端肯定是不支持的。或者由於產品需求的原因,某些交互或者展示差異較大等等。而項目針對某一端進行編譯、打包時,其他不相關的端代碼是無用、多餘的,如果保留的話,不僅會增加代碼體積,甚至會出現編譯報錯,因此我們需要藉助平臺代碼處理的能力來進行優化。平臺代碼的處理主要包含三部分:模塊導入、組件展示、業務邏輯。

主要思路是使用註釋和指定平臺的方式,讓特定的平臺代碼只在特定平臺生效,註釋關鍵字%%platform%%,比如%%RN%%表示React Native端獨有,%%MICRO%%表示PC微前端獨有,%%MICRO|Webview%%表示PC微前端、Webview 兩端生效。示例代碼如下:

import A from '@r2x/r2x-a'; // %%RN%%只在React Native端保留。
import B from '@r2x/r2x-b'; // %%MICRO%% 只在MICRO端保留。
import C from  '@/utils/c'; // 這是所有端生效的公共模塊。
import D from '@r2x/r2x-d'; // %%MICRO|Webview%%在MICRO、Webview多端生效的模塊。

4.2.4 小遊戲容器場景同構

實現react2x-game同構方案主要做的兩點:渲染層的兼容、業務層的兼容。

  1. 渲染層的兼容:實現遊戲引擎在多端環境下渲染能力的兼容(Canvas、WebGL)。
  2. 業務層的兼容:實現基礎API、項目流程、公共模塊的兼容,制定遊戲差異的個性化定製規範。

渲染層兼容

在上文,我們提到過“無論是Webview遊戲、小程序、小遊戲、美團小遊戲都爲我們提供了Canvas、WebGL控件”,很大程度地降低了我們兼容渲染層的複雜度。下面表單,是各端對於語法以及Canvas、WebGL、Document、Window等基礎功能的支持情況:

對象 Webview 微信小遊戲 微信小程序 美團小遊戲
語法 JavaScript JavaScript JavaScript JavaScript
Canvas 支持 支持 支持 支持
Canvas(離屏) 支持 支持 不支持 支持
WebGL 支持 支持 >2.11.0 支持
Ducument 支持 不支持 不支持 不支持
Window 支持 不支持 不支持 不支持

可以看出,在語法層面各端都支持了JavaScript語法,但是在執行環境以及基礎功能上的差異比較大,總結來說:

執行環境:小遊戲、小程序不具備DOM、BOM的能力(渲染引擎中會大量使用)。 基礎功能:小程序不支持離屏Canvas,在2.11.0版本以後纔開始支持WebGL。

爲了解決這些問題,我們設計開發了adaptor層,用來模擬document、window的能力。使遊戲引擎可以在非Webview的環境下正常的執行和調用BOM、DOM的基礎功能。同時,制定離屏canvas的適配方案,用來解決小程序無法支持離屏canvas的問題。爲了獲取到有效離屏canvas,我們製作了 “r2x-add-wxml-loader” ,在.wxml文件的loader階段自動注入額外的<canvas/>控件,並隱藏於手機屏幕之外,用於模擬遊戲引擎中的離屏canvas。

圖13

多端兼容構建

在構建層面,我們通過集成的多種個性化插件工具,對多端代碼進行差異處理。如:環境變量注入、各端適配代碼的混入、規範檢測、代碼解析和轉化等。針對小遊戲、小程序代碼和執行環境的特殊性,製作wx-build-plugin、lwxapp-build-plugin等用於處理小遊戲和小程序的打包工作。結合上文中提到的各類差異的處理方案,製作add-wxml-loader、transfrom-loader、wxss-loader等工具協助完成項目構建。如下圖14所示,構建之初會注入本次構建的環境變量,讀取和分析配置文件,集成和初始化構建工具集合,爲項目構建做準備。然後在構建環節,針對各端的差異進行差別處理,分析層針對不同文件進行解析,並在轉換層進行轉換和構建,最終生成各端需要的最終產物。

圖14

4.3 落地場景與效果

R2X-推廣頁容器場景同構 R2X-模塊化容器場景同構 R2X-小遊戲容器場景同構

效果收益

R2X在美團外賣業務中得到了廣泛的應用。截止2021年10月,R2X累計在美團內部已有二十多個部門在使用或者在調研中,總計落地了上百個工程、頁面,框架下載量達百萬次,頁面平均代碼同構率達90%以上。R2X生態體系在容器代碼複用與運維層面,累計爲美團節省成本上千人/日,並提升動態化頁面轉化5%-8%的成功率。

五、展望與總結

綜上所述,在美團外賣多元化業務形態和容器多樣性的情況下,跨容器複用成爲了發展的必經之路。而R2X在經歷了兩年的迭代下也取得了階段性的成果,在美團各個業務場景都完成了業務的落地覆蓋,針對公司的生態環境接入也做出了不少的基礎建設。我們相信跨容器多端代碼複用依舊是當前縮減項目交付週期,減少研發成本,提升研發效率的重要一環。但目前我們在很多複雜的業務場景下做的不夠完美,因此還有許多工作待完善,例如:

  • 開發體驗優化,目前想接入或正在接入的兄弟部門已經越來越多,如何減少接入成本,豐富基礎建設,優化開發體驗,幫助大家快速遷移接入,將是下一階段的重要課題。
  • 渲染性能優化,在美團外賣場景下性能優化一直是我們在兼顧高效生產的另一個重要指標。特別在小程序場景下,低端機型的性能體驗一直是業界瓶頸,如何突破這一難關將會是同構方案全面推廣的“敲門磚”。

最後,感謝各個相關研發團隊對R2X建設過程中的鼎力支持,R2X的發展離不開所有參與者日以繼夜的投入和貢獻,我們會持續基於R2X在終端容器領域進行更多探索。如果大家覺得R2X還不錯,或者對美團的R2X框架比較感興趣,歡迎跟我們一起交流探討。

作者簡介

正浩、寶石、彭震,均爲美團外賣終端團隊研發工程師。

招聘信息

美團外賣長期招聘Android、iOS、FE、Java高級/資深工程師和技術專家,歡迎有興趣的同學投遞簡歷到[email protected]

閱讀美團技術團隊更多技術文章合集

前端 | 算法 | 後端 | 數據 | 安全 | 運維 | iOS | Android | 測試

| 在公衆號菜單欄對話框回覆【2020年貨】、【2019年貨】、【2018年貨】、【2017年貨】等關鍵詞,可查看美團技術團隊歷年技術文章合集。

| 本文系美團技術團隊出品,著作權歸屬美團。歡迎出於分享和交流等非商業目的轉載或使用本文內容,敬請註明“內容轉載自美團技術團隊”。本文未經許可,不得進行商業性轉載或者使用。任何商用行爲,請發送郵件至[email protected]申請授權。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章