在前端越來越火的年代,逐漸衍生出類似React Native、Weex等開發套件。所達到的目的挺簡單的,達到在多個平台下共用一份代碼,節省開發成本,提高開發效率。其次,由於JavaScript語言的特殊性,能動態更新頁面而不需要發版。基於這兩點,越來越多的個人開發者&公司開始嘗試它們。
本文將從個人開發實踐項目出發,發表一些對於Weex的看法和在項目中的實戰經歷。不涉及具體原理和概念性的東西,讀者可以自行去Weex官網查閱。
大體上和React Native一致,都是一個“放大版”的JSBrdige。其核心無非就是自定義了一套DSL(.we),配合vue實現數據綁定、vdom等等功能。再通過native端與JS端的數據、API交互使得最終體現為native的調用過程。
而在這過程中,iOS用了自帶的引擎JavaScriptCore & Android則是Google V8。在這過程中有個坑,iOS版本Weex有內存洩漏的情況(Android沒有),原因是JS Framework(Weex JS端的主程)並沒有像V8一樣hidden class的行為,GC回收不是很及時。Weex開發團隊的同事發現了此bug,並在後續的版本中修復。
OK,我認為對於“應用框架者”來說,不用去care具體實現的原理。只需要了解怎麼使用即可,畢竟這只是一個工具。如果是為了學習,可以去閱讀,而對於“使用者”來說,快速地入門則是王道。
而Weex的使用,對於native來說,無非就是針對具體的業務場景實現Handler、Module、Component。
我們可以把Weex看做是一個提供了基礎套件的UI渲染庫。核心功能還是需要開發者自己來實現,比如:圖片下載邏輯、網絡請求、導航跳轉等等。
所以開發者首先要關注的就是需要靜態分析自己當前工程所需的功能,看看Weex需要你實現的handler中有哪些你要用到的,並實現它們。
比如在我的項目中,就需要實現圖片下載邏輯,於是實現並注冊。
[WXSDKEngine registerHandler:[CNCWeexImageLoaderImplement new] withProtocol:@protocol(WXImgLoaderProtocol)];
Module可以理解為JS端需要調用native才能處理的邏輯,並且在JS<->native進行交互。這麼說有點抽象,舉個具體的例子:比如在JS端想訪問native端的數據庫(coredata、realm等),就需要實現一個module來滿足JS調用native寫好的module以實現native的邏輯。
在我的實戰項目中,選擇用module的方式實現網絡請求與導航跳轉。[WXSDKEngine registerModule:@"urlRoute" withClass:[CNCWeexURLRouteModule class]];
[WXSDKEngine registerModule:@"networkRequest" withClass:[CNCWeexURLRouteModule class]];
Component很好理解,要實現一個跑馬燈UI的效果,在native端實現,並且注冊到JS。JS端調用,即可展示出跑馬燈。這就是Component,在JS滿足不了或者實現成本很高的時候,則可以在native端實現Component供JS調用。
由於第一次試水Weex,並沒有采取很復雜的UI,就沒有用Component。
JS中this關鍵字的用法與Objc不同,this的作用域僅在當前對象。而在JS中函數也算一個對象。如果在函數中套一個函數,此時用this,只能代表外層函數。而非Objc一樣代表整個最外層對象,需要注意!
業務中碰到一個場景,需要在某個場景,native端主動調用JS。而Weex提供給外部的API並沒有提供這樣的能力,僅僅是在JS主動調native方法時傳一個callback,並且在native方法執行完成時,callback銷毀。而業務場景卻需要在將來執行回傳下來的callback。翻看源碼,只能自己實現了。這裡給個思路:
其實在Weex的實現中(不貼源碼了),會判斷native實現的方法(即給JS調用的方法,比如module實現的方法)的入參類型。如果是聲明成WXModuleCallback,則Weex內部會進行處理,並轉成block給iOS(Android同理)。而如果不是WXModuleCallback,則會透傳一個String(weex標記的方法ID)下來,這很關鍵。於是我們可以投機取巧地把入參改成String,記錄下這個String。在後期想調這個JS方法時,寫如下代碼即可[[WXSDKManager bridgeMgr] callBack:weexInstance.instanceId funcId:aliveCallBackID params:params keepAlive:YES];
Weex相比React Native,坑還是比較多的。但是從“使用者”角度來說,Weex方便很多。但是對於存在很多復雜業務場景的開發者來說,必然會去學習其原理,而此時Weex相比RN就沒那麼友善了。
因為在阿裡,我更加支持Weex,也希望它變得越來越好。
無論采用哪種方式,兩者都能實現客戶端的動態化。而這對於一些多變的頁面來說,是一種新的選擇方式。
這是客戶端動態化系列的第二篇文章,讀者可以看前篇客戶端動態化系列之——URLRoute,相信你對動態化有更深的理解。