日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
微信小程序架構(gòu)分析(上)

 【引自第九程序的博客】相信不少上手試用了微信小程序開發(fā)者工具的開發(fā)者都會(huì)對(duì)其實(shí)現(xiàn)有些疑惑, 本文試圖對(duì)其架構(gòu)模型進(jìn)行一些解析。如有錯(cuò)誤之處,歡迎留言指出。

本文分為以下幾個(gè)部分:

  • 小程序調(diào)試技巧
  • 小程序主要模塊構(gòu)成
  • 小程序模塊間通信
  • 設(shè)計(jì)理念分析

小程序調(diào)試技巧

微信開發(fā)者工具默認(rèn)禁用了右鍵打開調(diào)試面板功能,我們可以修改開發(fā)者工具部分代碼移除該限制。

  • 找到 app.nw 項(xiàng)目根目錄,Mac 下為/Applications/wechatwebdevtools.app/Contents/Resources/app.nw
  • 使用 js-beautify 對(duì)代碼批量格式化:
 
 
 
 
  1. cd /Applications/wechatwebdevtools.app/Contents/Resources/app.nw 
  2. find . -type f -name '*.js' -not -path "./node_modules/*" -not -path "./modified_modules/*" -exec js-beautify -r -s 2 -p -f '{}' \;  
  • 注釋掉文件 app/dist/app.js 44 行和app/dist/components/simulator/webviewbody.js 149 行preventDefault 調(diào)用。101100 版本還需要修改 package.json 文件,去掉 --disable-devtools。

執(zhí)行完以上操作就可以右鍵打開頁面的調(diào)試面板了,需要特別注意的是,使用 view 頁面的面板后會(huì)導(dǎo)致 wxml 面板不可用,touch 事件無法響應(yīng)等種種問題,請(qǐng)慎重使用。

通過代碼可以發(fā)現(xiàn),在配置目錄下添加 config.json 文件,然后加入{isDev:true} 可以啟用開發(fā)者工具所謂的調(diào)試模式, 但是我在配置后程序無法正常啟動(dòng),只好暫時(shí)先放棄這種方式。

小程序主要模塊構(gòu)成

小程序自身分為兩個(gè)主要部分獨(dú)立運(yùn)行:view 模塊和 service 模塊。在開發(fā)者工具中,它們獨(dú)立運(yùn)行于不同的 webivew tag 中。

view 模塊負(fù)責(zé) UI 顯示,它由開發(fā)者編寫的 wxml 和 wxss 轉(zhuǎn)換后代碼以及微信提供相關(guān)輔助模塊組成。 一個(gè) view 模塊對(duì)應(yīng)一個(gè) webview 組件(也就是我們常規(guī)理解的一個(gè)頁面), 小程序支持同時(shí)多個(gè) view 存在。view 模塊通過 WeixinJSBridge 對(duì)象來跟后臺(tái)通信。

service 模塊負(fù)責(zé)應(yīng)用的后臺(tái)邏輯,它由小程序的 js 代碼以及微信提供的相關(guān)輔助模塊組成。 一個(gè)應(yīng)用只有一個(gè) service 進(jìn)程,它同樣也是一個(gè)頁面(至少在開發(fā)者工具內(nèi)如此,上線后可能運(yùn)行于 WeixinJSCore 之內(nèi)),與 view 模塊不同的是,它在程序生命周期內(nèi)后臺(tái)運(yùn)行,service 模塊通過與 view 模塊實(shí)現(xiàn)不同但接口格式一樣的 WeixinJSBridge 對(duì)象跟后臺(tái)通信。

小程序模塊間通信

(開發(fā)者工具內(nèi)各模塊通信圖)

做過微信開發(fā)相關(guān)的開發(fā)者會(huì)對(duì) WeixinJSBridge 這個(gè)對(duì)象有所了解,它就是負(fù)責(zé) UI 與后臺(tái) 進(jìn)行交互的一個(gè)中間層。應(yīng)用號(hào)的 WeixinJSBridge 相比與之前的微信 webview 多出 publish 和 subscribe 兩個(gè)公共方法來發(fā)布和訂閱事件,從而進(jìn)行雙向通信。

service 模塊的 WeixinJSBridge 對(duì)象在文件app/dist/weapp/appservice/asdebug.js 中定義, view 層的 WeixinJSBridge 在文件 app/dist/inject/jweixindebug.js 中定義。 盡管兩者都使用一樣的接口以及使用 postMessage 方法與后臺(tái)通信,但是其內(nèi)部所做的事情確是完全不同的, 例如 service 模塊可以直接通過 prompt 方法來通過 prompt調(diào)起底層組件,而 view 層的 WeixinJSBridge 只能發(fā)送消息 (參考 H5與Native交互之JSBridge技術(shù))。

我們來看一個(gè)典型的交互流程:

1.用戶點(diǎn)擊界面觸發(fā)事件

2.對(duì)應(yīng) view 模塊接收事件后將事件封裝成所需格式后調(diào)用 publish 方法發(fā)送:

 
 
 
 
  1. WeixinJSBridge.publish('PAGE_EVENT', data) 

data 參數(shù)舉例:

 
 
 
 
  1. "data": { 
  2.   "eventName": "onhidetap", 
  3.   "data": { 
  4.     "target": { 
  5.       ... 
  6.     }, 
  7.     "currentTarget": { 
  8.       ... 
  9.     }, 
  10.     "type": "tap", 
  11.     "timeStamp": 11457, 
  12.     "touches": [ ...  ], 
  13.     "detail": { 
  14.       ... 
  15.     } 
  16.   } 
  17. }, 
  18. "options": { 
  19.   "timestamp": 1475445858336 
  20. }  

3.后臺(tái)(開發(fā)者工具內(nèi)為 nwjs 運(yùn)行環(huán)境)將數(shù)據(jù)處理后發(fā)送給 service 模塊,數(shù)據(jù)形如:

 
 
 
 
  1. "to": "appservice", 
  2. "msg": { 
  3.   "eventName": "PAGE_EVENT", 
  4.   "data": { 
  5.     "data": { 
  6.       "eventName": "onhidetap", 
  7.       "data": { 
  8.         "target": { 
  9.           ... 
  10.         }, 
  11.         "currentTarget": { 
  12.           ... 
  13.         }, 
  14.         "type": "tap", 
  15.         "timeStamp": 75329, 
  16.         "touches": [ ...  ], 
  17.         "detail": { 
  18.           ... 
  19.         } 
  20.       } 
  21.     }, 
  22.     "options": { 
  23.       "timestamp": 1475445858336 
  24.     } 
  25.   }, 
  26.   "webviewID": 0 
  27. }, 
  28. "command": "MSG_FROM_WEBVIEW" 
  29. }  

4.service 模塊的 WeixinJSBridge 內(nèi)回調(diào)函數(shù)依據(jù)傳來數(shù)據(jù)找到對(duì)應(yīng) view 的 page 模塊后執(zhí)行 對(duì)應(yīng)名為 eventName 指向的函數(shù)

5.回調(diào)函數(shù)調(diào)用 this.setData({hidden: true}) 改變 data,serivce 層計(jì)算該頁面 data 后向后臺(tái)發(fā)送 send_app_data 和 appdataChange 事件,具體數(shù)據(jù)格式如下:

 
 
 
 
  1. "appData": { 
  2.   "page/index": { 
  3.     ... 
  4.   } 
  5. }, 
  6. "sdkName": "send_app_data", 
  7. "to": "backgroundjs", 
  8. "comefrom": "webframe", 
  9. "command": "COMMAND_FROM_ASJS", 
  10. "appid": "touristappid", 
  11. "appname": "chat", 
  12. "apphash": 70475629, 
  13. "webviewID": 100000 
  14. }  
 
 
 
 
  1. "eventName": "appDataChange", 
  2. "data": { 
  3.   "data": { 
  4.     "data": { 
  5.       "hidden": true 
  6.     } 
  7.   }, 
  8.   "options": { 
  9.     "timestamp": 1475528706311 
  10.   } 
  11. }, 
  12. "sdkName": "publish", 
  13. "webviewIds": [ 
  14.   0 
  15. ], 
  16. "to": "backgroundjs", 
  17. "comefrom": "webframe", 
  18. "command": "COMMAND_FROM_ASJS", 
  19. "appid": "touristappid", 
  20. "appname": "chat", 
  21. "apphash": 70475629, 
  22. "webviewID": 100000 
  23. }  

6.后臺(tái)(文件 dist/components/simulator/webviewbody.js) 接收到appDataChange 事件數(shù)據(jù)后再將數(shù)據(jù)進(jìn)行簡單封裝, ***轉(zhuǎn)發(fā)給到 view 層。 具體數(shù)據(jù)格式為: 

 
 
 
 
  1. "to": "webframe", 
  2. "msg": { 
  3.   "eventName": "appDataChange", 
  4.   "data": { 
  5.     "data": { 
  6.       "data": { 
  7.         "hidden": true 
  8.       } 
  9.     }, 
  10.     "options": { 
  11.       "timestamp": 1475528706311 
  12.     } 
  13.   }, 
  14.   "sdkName": "publish", 
  15.   "webviewIds": [ 
  16.     0 
  17.   ], 
  18.   "to": "backgroundjs", 
  19.   "comefrom": "webframe", 
  20.   "command": "COMMAND_FROM_ASJS", 
  21.   "appid": "touristappid", 
  22.   "appname": "chat", 
  23.   "apphash": 70475629, 
  24.   "webviewID": 100000, 
  25.   "act": "sendMsgFromAppService" 
  26. }, 
  27. "command": "MSG_FROM_APPSERVICE", 
  28. "webviewID": 0, 
  29. "id": 0.10577065353216675 
  30. }  

7.view 層的 WeixinJSBridge 接收到后臺(tái)的數(shù)據(jù),如果 webviewID 匹配則將 data 與現(xiàn)有頁面 data 合并, 然后就是 virtual dom 模塊進(jìn)行 diff 和 apply 操作改變 dom。

小程序模塊間消息傳遞除了界面事件和應(yīng)用數(shù)據(jù)還包括觸發(fā)原生方法、握手以及生命周期等類型, 盡管處理對(duì)象和處理方式不同,大體流程跟上面是一樣的。

view 模塊和 service 模塊的 WeixinJSBridge 都使用了 postMessage 接口 (參考MDN 文檔) 與后臺(tái)通信,但是由于該接口無法直接與 nwjs 后臺(tái)進(jìn)程通信,所以開發(fā)者工具會(huì)將 app/dist/contentscript/contentScript.js 文件做為contentScript 注入到 view 模塊和 service 模塊所在頁面,contentScript.js 的代碼提供了 message 消息到 chrome.runtime通信接口的轉(zhuǎn)換。

微信開發(fā)者工具擴(kuò)展了 devtools 提供了 AppData 面板,開發(fā)者可以修改里面數(shù)據(jù)然后直接看到 view 界面的變化效果。這里修改數(shù)據(jù)后 nwjs 會(huì)將消息發(fā)送給 service 層,之后發(fā)生的事就跟上面 4 5 6 步一樣:service 傳遞消息給 nwjs,***到 view 層。

設(shè)計(jì)理念分析

小程序這樣的分層設(shè)計(jì)顯然是有意為之的,它的中間層完全控制了程序?qū)τ诮缑孢M(jìn)行的操作, 同時(shí)對(duì)于傳遞的數(shù)據(jù)和響應(yīng)時(shí)間也做到的監(jiān)控。一方面程序的行為受到了極大限制, 另一方面微信可以確保他們對(duì)于小程序內(nèi)容和體驗(yàn)有絕對(duì)的控制。

我們?cè)谛〕绦虻?js 代碼里面是不能直接使用瀏覽器提供的 DOM 和 BOM 接口的,這一方面是因?yàn)?js 代碼外層使用了局部變量進(jìn)行屏蔽,另一方面即便我們可以操作 DOM 和 BOM 接口,它們對(duì)應(yīng)的 也是 service 模塊頁面,并不會(huì)對(duì)頁面產(chǎn)生影響。

這樣的結(jié)構(gòu)也說明了小程序的動(dòng)畫和繪圖 API 被設(shè)計(jì)成生成一個(gè)最終對(duì)象而不是一步一步執(zhí)行的樣子, 原因就是 json 格式的數(shù)據(jù)傳遞和解析相比與原生 API 都是損耗不菲的,如果頻繁調(diào)用很可能損耗 過多性能,進(jìn)而影響用戶體驗(yàn)。

理解了以上機(jī)制,再對(duì) view 模塊和 service 模塊的 WeixinJSBridge 加以改造,我們便不難做到讓 小程序跑在自己的環(huán)境下,這樣就可以做些手機(jī)調(diào)試以及單頁面測(cè)試等操作。


分享名稱:微信小程序架構(gòu)分析(上)
分享路徑:http://m.5511xx.com/article/copgpde.html