歷經近20個月打磨,滴滴跨端方案chameleon終於開源了github.com/didi/chamel…, 真正專注於一套程式碼執行多端。
背景
微信月活10億月活(超過網民數量,使用者多個賬號?)、支付寶4億月活、百度3.3億月活;2018 Q3中國Android手機佔智慧手機市場超過80%;無論BAT還是Android快應用都是中國網際網路使用者的真正使用者入口,作為小型網際網路公司都希望能搭上小程式的風口,從而蹭一波流量。
計算機技術歷史發展告訴我們,每一種新技術出現都會經歷"各自為政"的階段,小程式技術也不例外。微信小程式作為首創者,雖然其他小程式都在技術實現原理、介面設計刻意模仿,但是作為一線開發者面對同樣的應用實現往往需要重複開發、測試,從前1單位的工作量變成了N單位的工作量。
滴滴的研發工程師是其中最顯著的"受害者"之一,滴滴出行在微信錢包、支付寶、Android快應用都有相關入口,使用者流量佔比不低。
各類小程式已經能覆蓋中國所有網民,從Facebook在2013年開源react,這個專案本身越滾越大。從最早的WebUI引擎衍生的ReactNative專案,目標更是巨集偉。
Vue.js於2014年左右釋出,逆流而上佔據了大量使用者群體,2016年阿里巴巴也基於vue釋出了weex專案,可以用vue編寫NativeAPP。
Google在2018年末正式釋出了面向未來的跨Andoid、IOS端Flutter1.0.0,作為面向未來的跨端框架,前景一片光明。
解決方案
雖然不同各端框架環境千變萬化,無論各類小程式、Weex、React-Native、Flutter、快應用,它們萬變不離其宗的是MVVM架構設計思想。Chameleon希望既能用一套程式碼完成所有端需求,將相同的業務邏輯完成收斂到同一層系統裡面,又不會因為專案的抽象一致導致可維護性變差。
讓MVVM跨端環境大統一:以各個跨端技術(Weex、React-Native、WebView瀏覽器、Flutter)和產品業務(微信小程式、快應用、支付寶小程式、百度智慧小程式、今日頭條小程式、其他各類小程式)的共同技術特點——MVVM架構設計, 以統一MVVM跨端架構平臺為目標的程式語言框架Chameleon(任意使用MVVM架構設計的終端,都能以Chameleon開發並執行)。
View:
ChameleonSDK包括各類小程式、web端、客戶端(React-Native、Weex、Flutter),目前支援微信小程式、Web、Weex三類,後續支援更多MVVM為標準的端。
View Model:
CML(Chameleon MarkupLanguage)是框架設計的一套標籤語言,結合基礎元件、事件系統、資料繫結,可以構建出頁面的結構。同時為了降低學習成本支援類VueTemplate。
原理
久經考驗
2017年時微信小程式釋出,滴滴作為白名單使用者首先開始嘗試接入。這時候我們專門成立了一個1、2人的小專案組,完成一個名為MPV的專案,一期目標是“不影響使用者發揮,不依賴框架方的原則性實現一套程式碼執行web和微信小程式”。MPV研發完成後,在多個專案實踐中,確實完成了超過90%程式碼重用,總體上開發效率和測試效率都有了明顯提升,同時暴露出更多問題:
- 可維護性問題,沒有隔離公用程式碼和各端差異程式碼。
- 方向選擇錯誤,MPV使用了小程式語法標準(小程式的生命週期、API介面等),導致使用者使用上無法清晰理解使用規範。
- 各端周邊小型差異點太多。
- 模板DSL語法不規範。
- 兩端介面效果不一致。
- 多端除錯成本高。
- 工程化建設落後。
- 不能直接使用各端已有生態元件,即缺乏標準規範接入某個端已有開源元件。
2018年4月我們把跨端專案規模進一步擴大,跨N端的解決方案命名為Chameleon/kmiln/,簡寫CML,中文名卡梅龍;中文意思變色龍,意味著就像變 色龍一樣能適應不同環境的跨端整體解決方案。
Chameleon在MPV的實踐積累下,不僅解決了遇到的各種可維護性問題,後續的規劃更加明確,目標真正專注於讓一套程式碼執行多端,提供標準的MVV M模式統一各類終端。
經過一年數十位前端開發人員在上百頁面中的實踐經驗積累,在本週正式開源:github.com/didi/chamel…。。
生產應用舉例
易用性好
一套程式碼執行多端理念,被人挑戰最多的如何保證易用性。
- 開發快,整體開發流程要高效。
- 簡潔性,各端開發定製化空間大,且公用程式碼不會混雜某端程式碼。
- 效能好,不能增加產出檔案包大小。
- 一致性,多端實現效果一致。
開發快 | |||
---|---|---|---|
關鍵詞 | 工程化開發 | 專案級統一 | 元件級統一 |
描述 |
收集最優秀的工程化功能: 多種資料Mock、資源定位、代理除錯、LivereLoad等, CML不用僅僅是跨端,更能幫助開發者高效開發單個端。 |
當多個端整個業務高度一致時,能用一套專案程式碼執行多端 |
已經用原生小程式開發程式碼,已經用vue開發的web頁面,2者有重複開發元件如登入
|
簡潔性(各端開發定製化空間大) | 效能好 | 一致性 | ||
---|---|---|---|---|
關鍵詞 | 多型協議 | 產出資源包大小,只保留單端程式碼 | 語法檢查 | 多端一致性還原 |
描述 | 多型協議可用於多級,使用者自由切換,由上至下:方法級、元件級、頁面級、應用級 | 編譯階段將會只保留要匯出的部分程式碼,內建元件和API按需打包 | 為了保障各個端實現效果一致,不用挨個除錯各端,儲存時做語法檢查,暴露潛在問題。 | 在編譯、runtime層大量工作保障實現效果一致 |
多型協議
多端合併後各端差異化實現在所難免,一開始是差異化程式碼和業務邏輯混雜在一起。這就尷尬了,如果你覺得以上不復雜,假設有4、5個端呢,業務邏輯摻雜跨端邏輯,產品邏輯別打斷,可讀性差,需求變更,牽一髮動全身,每個端都要測試,跨端程式碼效率變得適得其反。
下圖各端差異化程式碼也和邏輯混合在一起
多型協議設計的靈感來自於Apache Thrift - 可伸縮的跨語言服務開發框架,本質上跨端也屬於跨語言。
它能讓Chameleon開發者快速接入各個客戶端底層功能或者差異化業務實現,避免可讀性差、可維護性差的問題。
多型協議通過定義標準介面(interface),各端模組各自獨立實現,編譯時和執行時對實現的介面輸入輸出做檢查。
主要2個目標:
- 保障多端可維護性
- 編譯時拆分多端程式碼
當使用者按照標準規範擴充套件個別產品效果多端不一致或特定底層能力多端不一致的的功能時,多型協議可以有效隔離公用程式碼和各端差異程式碼,保證”河水不犯井水“。
舉例:當你像開發一個圖表功能元件時,可能用到 echarts :
- 在專案中分別按照web版本
npm install echarts
和微信版本下載相關檔案 - 然後定義一個多型元件 charts
- 在 charts/charts.interface 定義該元件的輸入和輸出
- 分別在 charts/charts.wx.cml 和 charts/charts.web.cml 裡面呼叫微信版本(可使用微信小程式元件資料夾)和web版本(可呼叫.vue字尾檔案)
- 最後就能在專案中使用該元件
產出包裡面只包含該元件其中一端的程式碼;因輸入輸出的限制,該元件呼叫上完全一致,不用根據某端做特殊邏輯處理。你可以將該echart多型元件單獨放置在一個倉庫裡面單獨維護併發布;其他人無需關係內部細節,直接npm install echart
即可使用。
學習成本低
VM層的CML語法是關聯檢視層和邏輯層的抽象DSL,其有學習成本問題是被熱心很多幫助我們的同學提的最多建議,本身其CML學習成本已經非常低,無非是資料雙向繫結、事件繫結、元件樹、條件語句、迴圈遍歷等等。一開始我們是拒絕的,後來綜合考慮之下,還是妥協支援了類vue語法,讓開發者更快上手CML。
漸進式接入
很多人已經開發小程式了,又不願意大多闊斧重新改造,也希望使用CML?當然可以,2種方式使用CML:
說明/型別 | 整個專案使用CML | 公用元件使用CML |
---|---|---|
關係圖 | ||
說明 | 業務層需求在各端環境高度類似, 原本需要針對不同端重複開發、重複測試, 那麼使用Chameleon將整個專案”從上至下“都用一套程式碼執行。 |
原本公用元件需要重複開發、重複測試, 使用一套程式碼開發公用元件, 各個端可以直接使用公用元件 |
舉例 | 首頁、詳情頁、訂單 | 分享元件、支付元件、地圖元件、picker元件 |
業內對比
業內其他框架和我們的目標不一樣,我們是希望真正一套程式碼執行多端,而其他框架無非是“某個小程式語法增強”或者“推廣某個框架寫小程式 ”,但卻是有重合點,列舉一下功能對比:
後期規劃
方向 | 子方向 | 執行專案 |
---|---|---|
易用性加強 |
|
|
框架優化 |
|
|
端品類擴充套件 |
|
|
元件擴充套件 |
|
|
端能力擴充套件 |
|
|
流程優化 |
|
|
服務擴充套件 |
|
|
理想主義
- 我們忍受不了自己的時間浪費在重複勞動上。
- 要麼不做要做就到極致,一套程式碼執行多端本來就是理想主義,這條路很艱苦,我們卻偏執的堅信一定要盡最大努力做出來,作為一個不那麼自信的人,不做到好用是不敢釋出出來的。
- CML框架各個細節都要做到極致,我們不能容忍有設計上的缺陷,所以常常CML週會上團隊成員討論6個小時直到深夜。
常見問題: cmljs.org/doc/framewo…
歡迎加入貢獻程式碼: didi/chameleon