首先要介紹一下我們是怎麼做到資料綁定的,首先,我們對上層撰寫的代碼遵循了傳統的 mustache 書寫習慣。即:
我們的 transformer 對這樣的文法的解析思路非常簡單直接,即:
不含 mustache 文法的值,直接做為最終傳回值
含 mustache 文法的值 (如 <code>{{xxx}}</code>),轉換為:<code>function () {return xxx}</code>
是以上面的模闆最終會被轉換成:
在用戶端的 javascript 引擎中,我們會進行這樣的判斷:
隻要是函數類型,就進行資料綁定,否則一次性指派,簡單易懂易用。
這樣在相應的資料發生改寫的時候,界面結構和樣式會通過 <code>_bindkey</code> 和 <code>updater</code> 自動觸發更新。
關于如何在 javascript 上實作資料監聽,也算是一個很重要的細節,不過市面上已經有大把優秀的實作案例了,我們也沒有在這個環節上做特别的事情,是以不做贅述。
在 transformer 中,我們主要的工作就是對 html、css、javascript 代碼進行解析和重組。這裡我們用到了三個非常重要的庫:
用 htmlparser 可以把 html 轉換成 json
用 cssom 可以把 css 轉換成對象供二次處理
用 uglify-js 可以把 javascript 代碼進行細節解析處理
而且因為有了 transformer,我們可以把傳統 mvvm 需要在用戶端甚至 dom 上完成的模闆解析、資料綁定文法解析等工作提前處理完畢。是以免去了用戶端運作時現解析模闆源檔案的負擔。更酷的是,因為模闆解析是不依賴真實 dom 的,是以我們可以大大方方的把文法設計成 <code><img src="{{xxx}}"></code> 而不必擔心任何副作用。而進階的表達式、過濾器等資料綁定文法也都可以在 transformer 這一層提前處理好,這樣在撰寫體驗持續增強的情況下,運作時并不會産生額外的負擔——這都要歸功于我們引入了這一層 transformer
我們為 native 界面調試設計了貼心的遠端調試工具,主要解決三個痛點問題:
調試 javascript 代碼,任意設定斷點 debug
運作指令行代碼 (console) 對程式做實時的判斷
渲染結構的樹形審查
解決問題的辦法是:
用戶端設定一個開關,可以把 js bridge 對接到一個遠端的 websocket 伺服器,而不是對接到本地的 javascript 引擎
本地準備一個網頁,其中運作了完整的 javascript 引擎的代碼,并且也可以連結到一個遠端的 websocket 伺服器,這樣用戶端的 native 層和本地網頁裡的 javascript 引擎就串聯起來了
原本通過 js bridge 的雙向通信内容可以被 websocket 連接配接記錄下來
javascript 引擎裡的所有代碼都可以通過本地浏覽器的開發者工具進行 debug 和 console 控制
開發一個簡易的 chrome devtools extension,可以得到 weex 執行個體的界面結構,并以目錄樹的方式呈現出來。
這樣,一個用戶端開關,一個 websocket 伺服器,一個本地的 javascript 引擎頁面,一個開發者工具擴充,我們就實作了 weex 的遠端調試。
weex 的 javascript 引擎作為一個相對底層的項目,品控需要做到非常嚴格和極緻,否則一個小小的失誤在用戶端長期運作之後都有可能帶來災難性的後果。
本次 weex 的開發當中,我們認真實踐了基于 mocha、chai 和 sinon 的單元測試,每個源代碼的檔案夾都放了一個名叫 <code>__test__</code> 的檔案夾,裡面放了這個目錄下所有同名的 javascript 檔案,每個檔案的内容都是目前檔案夾内對應檔案的測試用例。
在項目中後期,我們還引入了集團内部的一個 ci 系統,每次開發新功能,先開一個分支,然後寫測試用例,最後進行代碼實作知道跑通所有的 test case,搞定之後發起 merge request,ci 系統會自動線上上運作所有的回歸測試,再次驗證其正确性和各項名額。
其實有關項目品控的話題還有很多,我們也在逐漸實踐當中。
我們已經在内部版本實作了簡單的服務端渲染,有了這個東西會怎樣呢?
一旦我們可以在服務端直接渲染出界面的 json 結構,用戶端就可以繞過 javascript 解析過程,直接根據 json 結構把界面渲染出來。與其對應的邏輯控制稍後也會初始化好,并和界面效果最終保持同步,但在整個過程中,首屏加載的時間會進一步縮短。而且,更令人興奮的是,如果目前界面剛好沒有互動邏輯,甚至後期的 javascript 也不需要參與了,這是一條更短的鍊路!
通過對 weex 技術方案的探索,我們把元件化開發、transformer 機制、同構等理念反哺到 html5 開發,會有什麼樣的驚喜呢?
那就是一個極簡的針對無線前端的 html5 mvvm 庫:我暫時取名叫做 v.js
v.js 的名字來自著名的 mvvm 庫 vue.js,我希望這個庫更适合移動端,目前它可以具備所有 mvvm 的核心功能,通過 transformer 提前解析模闆,運作時更快速,體積是 vue.js 的 1/3,而且支援服務端的同構。這些都是基于移動端現狀的二次改進,目前還在細節構思和研發當中。希望不久的将來可以跟大家見面。
篇幅有限,寫了三篇還是覺得不夠,期待和大家更多的交流。
阿裡無線前端團隊更多精彩的内容還在後面排隊,我這邊對無線電商動态化方案的思考就先寫到這裡了:)