前言
經過近一年的開發,上周 支付寶小程序 終于得以公測,期間由于我們的疏忽將 wx 的部分示例放到了我們的開放文檔中,給公司造成了麻煩,在此團隊成員向各位同事表示歉意。但正如道歉信所言,我們的底層架構是完全基于螞蟻金服多年的技術積累,踩過無數的坑而形成,且一直在完善中。之前一年我也 all in 在小程序中出于保密很少發文(其實我變懶了??),經過本周的平穩運行,我想解釋下支付寶小程序的技術架構,在公司內部希望大家能夠對支付寶小程序有更多的了解。
歷程
回想近一年的開發,技術選型多次變更,歷程曲折而又折騰,可謂苦中作樂。在去年 9 月份響應號召,我們先后嘗試了 react-native,react web,以及基于純開放 jsapi 的 h5 等方案,最終在年初確定了對外的支付寶小程序采用 react web 方案,但我們并沒有放棄 react-native 方案,目前穩定運行在螞蟻財富客戶端中。
框架
小程序框架的設計目標為無縫運行在桌面 web 開發環境(IDE),客戶端原生環境(react-native),客戶端 web 環境中,運行效果示意圖:
因此框架順應潮流命名為 AppX(Application framework for X platform). 也是支付寶小程序中引入的 js 文件名稱。
設想的整體方案中還包括了 native SDK 的支持,后續分別由 nebula 以及小程序 native 容器承擔了該角色.
架構圖
每個小程序的代碼分為兩部分,分別運行在 worker(JSEngine) 以及 render 渲染層中, render 可以有多個, worker 只有一個,方便 app 數據在頁面間的共享和交互。
worker 運行小程序的邏輯處理代碼,包括事件處理,api 調用以及框架的生命周期管理。
render 運行小程序的渲染代碼,主要包括模版/樣式和框架的跨終端的 js 組件或 native 組件,獲取邏輯層的數據操作渲染引擎(React/ReactNative)進行渲染。
worker 和所有的 render 都建立連接,將需要渲染的數據傳遞給對應的 render 進行渲染,worker 也會將 api 調用轉給 native SDK 處理。
render 則將組件的觸發事件送到對應的 worker 處理,同時接受 worker 的 setData 調用 React 重新渲染。 render 可以看作一個無狀態的渲染終端,狀態統統保留在 app 級別的 worker 里面,因此 render 可以看作 react 單頁 app 中的 dumb component,worker 可以看作 react 單頁 app 中的 redux。
IDE 開發環境
運行在 electron 中,通過空白 webview 模擬單獨的 js 線程運行小程序的 worker 代碼(可以保持調試窗口的穩定性以及定制性) ,通過 electron 進程通信機制將邏輯處理產生的渲染數據渲染到對應的 webview 頁面.
客戶端 web 環境
render 包括一個 UIViewController(Activity) 以及 webview,worker 為每個應用提供獨立的唯一線程,其中 ios 通過 jscore, android 通過系統的 service worker 運行小程序 app 的 worker 部分代碼,并和當前應用的所有 webview 建立連接,用戶將數據從 jscore 線程中傳遞給 webview 渲染,同時客戶端通過攔截 jscore 線程的 api 調用提供 native 功能。
客戶端 react-native 環境
render 包括一個 UIViewController(Activity) 以及 react-native root view,worker 通過 react-native 共享 bridge 實現。worker 可以通過 react-native NativeModules 和客戶端直接通信,setData 則更簡單了就是 react-native 自帶的 setState 通信機制。