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

語言: CN / TW / HK

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]申請授權。