最近一段時(shí)間在研究實(shí)現(xiàn)微信小程序和小游戲編譯打包和運(yùn)行環(huán)境平臺(tái)開(kāi)發(fā)。
目前基本可以支持微信基礎(chǔ)庫(kù) 2.8.2 功能迭代了。
在此之前網(wǎng)上有存在開(kāi)源的一些基于微信基礎(chǔ)庫(kù)版本 1.0 的一些參考。核心作者是由開(kāi)源大牛 啟明兄 的 wept 項(xiàng)目基礎(chǔ)上構(gòu)建的 (目前有幸和啟明兄成為同事對(duì)這個(gè)小程序整體的架構(gòu)理解幫助了我很多)。
由于 wept 的運(yùn)行環(huán)境是基于微信基礎(chǔ)庫(kù) 1.0 的版本上實(shí)現(xiàn)之后也不維護(hù)了,時(shí)間上是 2016 的在后續(xù)的更新的版本中新加的一些特性如自定義組件 npm 包很多 api 等開(kāi)發(fā)實(shí)現(xiàn)都不支持,最主要是的微信在后續(xù)架構(gòu)中更換底層的通信方式采用了 webstock 的方式等一些其他變化。
最開(kāi)始的時(shí)候也在網(wǎng)上找了很多的資料,看了有一些人寫的解析微信小程序架構(gòu)的文章,從中學(xué)習(xí)了解了很多,
但如果想模擬實(shí)現(xiàn)出來(lái)這么個(gè)東西還是有蠻迷糊的,所以我想通過(guò)我們所實(shí)現(xiàn)的過(guò)程來(lái)一點(diǎn)點(diǎn) 從現(xiàn)象 看本質(zhì) 來(lái)解析下微信小程序編譯和運(yùn)行原理。
凡事對(duì)自己多點(diǎn)信心,多堅(jiān)持下,多學(xué)習(xí)下,想想我們遇到的問(wèn)題,當(dāng)時(shí)感覺(jué)我,搞不定了,弄不了,最后隨著時(shí)間的推移和認(rèn)知的迭代問(wèn)題總會(huì)慢慢消滅掉。
整個(gè)小程序框架系統(tǒng)分為兩部分:邏輯層(App Service)和 視圖層(View);
小程序提供了自己的視圖層描述語(yǔ)言 WXML 和 WXSS;
基于 JavaScript 的邏輯層框架,并在視圖層與邏輯層間提供了數(shù)據(jù)傳輸和事件系統(tǒng)他們兩個(gè)線程里運(yùn)行;
視圖層使用 WebView 渲染,邏輯層使用 JSCore 運(yùn)行, 視圖層和邏輯層通過(guò)系統(tǒng)層的 JSBridage 進(jìn)行通信,邏輯層把數(shù)據(jù)變化通知到視圖層,觸發(fā)視圖層頁(yè)面更新,
視圖層把觸發(fā)的事件通知到邏輯層進(jìn)行業(yè)務(wù)處理。
下面通過(guò)微信開(kāi)發(fā)工具來(lái)展示說(shuō)明,小程序邏輯層的 javascript 代碼是運(yùn)行在 NW.js 中,視圖層是由 Chromium 60 Webview 來(lái)渲染的
他們之間是通過(guò) webstock 協(xié)議來(lái)通信的。
我們先打開(kāi) 微信開(kāi)發(fā)工具官方 demo 如圖:
從上圖和我們的一些理解我們知道微信小程序的文件格式主要組成:
我們后面分析的主要代碼都在 package.nw 里面和 core.wxvpkg。
這些文件在后面實(shí)現(xiàn)過(guò)程中都會(huì)使用說(shuō)明用途的。
core.wxvpkg 解壓代碼上傳在 unwxvpkg 大家有興趣可以自己先試試。
接下來(lái)我們回到開(kāi)發(fā)者工具中打開(kāi):
如果你更改 appservice 的 webview 的話微信還會(huì)給你各種 alert 彈框,反正應(yīng)該就是不想讓你分析他的代碼
點(diǎn)擊確定消都消不了只能重新重啟編譯了 有點(diǎn)小惡心啊
我們第一步還是打開(kāi):微信開(kāi)發(fā)者工具–》調(diào)試–》調(diào)試微信開(kāi)發(fā)者工具
在控制臺(tái)輸入
復(fù)制代碼
document.getElementsByTagName('webview')
可以看到對(duì)應(yīng)的有 4 個(gè) webview, 我們先要關(guān)注的是第一個(gè) webview 因?yàn)槟泓c(diǎn)開(kāi)可以發(fā)現(xiàn)第一個(gè)對(duì)應(yīng)的就是渲染層的 webview
后面的幾個(gè)可以先不關(guān)注,后續(xù)我們會(huì)詳解
然后我們執(zhí)行命令打開(kāi)第一個(gè) webview:
復(fù)制代碼
document.getElementsByTagName('webview')[0].showDevTools(true,null)
可以看到如圖
現(xiàn)在我們就可以看到微信頁(yè)面渲染層的頁(yè)面結(jié)構(gòu)了
上面的 webview 可以找到對(duì)應(yīng)的頁(yè)面層的結(jié)構(gòu),那么 appservice 要怎么找到呢?
其實(shí)最簡(jiǎn)單的我們直接在首頁(yè)里面的控制臺(tái)打 document 就可以直接看到展示的邏輯層代碼
(我的做法是從寫了微信的 alert 和基礎(chǔ)庫(kù)的一些文件都可以看到這個(gè)結(jié)構(gòu))
接下面我們看下微信小程序的基礎(chǔ)庫(kù)庫(kù)文件
方法是我們?cè)谑醉?yè)控制臺(tái)里面輸入 openVendor()
我們可以看到彈出的文件系統(tǒng),這里面對(duì)應(yīng)的就是你選擇本地的
.wxvpkg 包里面這個(gè)基礎(chǔ)庫(kù)文件的 WAWebview.js 和 WAService.js,對(duì)應(yīng)這兩個(gè) webview 里面的 js 引用你可以仔細(xì)觀察下.wxvpkg 文件解包后的格式:
這里告訴大家一個(gè)方法劫持他的運(yùn)行命令
找到微信開(kāi)發(fā)者工具 wcc 和 wcsc 的地方然后新建兩個(gè)同名的腳本,然后把原文件從命名,然后重啟微信開(kāi)發(fā)者工具 一定要重啟不然不生效
本篇只是簡(jiǎn)單描述了一些關(guān)鍵文件的描述。
后面我會(huì)對(duì)關(guān)鍵文件進(jìn)行一一分析描述下他具體做了什么,為什么用到它。
下一篇會(huì)給大家?guī)?lái)渲染層和邏輯層的具體頁(yè)面文件內(nèi)容結(jié)構(gòu)解析,以及 webstock 通信架構(gòu)在微信開(kāi)發(fā)者工具里面的運(yùn)用,可以先給大家看下。

其實(shí)他們之間的協(xié)調(diào)工作以及公開(kāi)對(duì)外的 wx. 對(duì)象上面的 api 都是通過(guò) websocket 協(xié)議消息實(shí)現(xiàn)的。