《微信小程序七日談》系列文章:javascript
本系列的文章並不是初學教程,而是筆者在具體開發過程當中遇到的問題以及部分解決方案。css
筆者參與的小程序項目開發也進入尾聲了,坑也踩得七七八八,對於哪些沒有涵蓋和深刻使用的功能筆者就不班門弄斧了。html
前幾篇文章講了那麼多細節也好,策略也好,都是應用層面的東西。自微信小程序公佈以來就有先行者不斷的探索小程序背後的運行機制。小程序的開發語法和API與前端工程師熟悉的html/js/css很是類似,因此會令不少人疑惑小程序與普通的HTML5應用到底有什麼區別。這篇文章其實將小程序的基本運行機制剖析的差很少了,簡單歸納就是:前端
既然已經有先行者得出告終論,爲啥還要寫這篇文章呢?固然是爲了湊齊七篇啦,哈哈哈...java
開玩笑!這篇文章的目的不是重複別人的結論,而是將筆者研究小程序開發工具源碼的一些心得和結論記錄下來,以方便你們後續更深刻的探索。node
第一步是找到小程序devtool的源碼,以mac系統爲例,源碼的打開方式以下圖:
程序員
其餘的文件不用理會,咱們要研究的主要代碼在Content/Resources/app.nw/dist
目錄下,這個目錄包括devtool的功能代碼以及對小程序進行執行、編譯、打包、上傳等功能的代碼。固然,這些代碼都是通過混淆的,讀起來還挺費勁(攤手~web
須要着重注意的是Content/Resources/app.nw/dist/weapp
目錄,以及commit和trans兩個子目錄:
小程序
從文件的命名上大體能夠猜到每一個文件對應的功能:微信小程序
既然咱們知道小程序會進行構建打包流程,想得知小程序運行機制最好的辦法就是研究構建完畢以後的代碼。有了這個目標以後,下一步就是查看devtool的日誌獲取小程序構建以後的代碼存放位置。
Content/Resources/app.nw/dist/common/log/log.js
是負責管理devtool日誌功能的文件,其中有這樣一段代碼:
const a = require('fs'), b = require('log'), c = require('path'), d = require('../../config/dirConfig.js'), e = d.WeappLog;
其中e
即是日誌文件的存放目錄,而後咱們追溯到config/dirConfig.js
中發現目錄路徑是由nw.App.getDataPath()
生成的,這個函數是node-webkit提供的API,生成結果的規則在不一樣的操做系統下有差別,惋惜筆者並無找到相關的說明(沮喪)。
可是這次代碼的探索並不是沒有收穫,起碼咱們知道了日誌文件存放的目錄名爲「WeappLog」,咱們可使用強大的命令行從硬盤中搜索此目錄:
mdfind WeappLog
你們能夠參考這篇文章瞭解
mdfind
命令的用法
從輸出結果能夠得知日誌文件在Mac系統的存放目錄爲/Users/<用戶名>/Library/Application Support/微信web開發者工具/WeappLog
。進入目錄後就會發現不少以.log
爲後綴的日誌文件:
找到日誌文件後即可以從devtool的執行日誌中獲取小程序被構建後的代碼存放位置。固然,第一步是要講小程序進行構建,操做方法是在小程序開發工具的「項目」菜單」中點擊」預覽「:
成功後再日誌文件中會出現這麼一行記錄:
[Wed Jan 18 2017 15:20:24 GMT+0800 (CST)] INFO pack.js create /Users/<用戶名>/Library/Application Support/微信web開發者工具/Weappdest/1484724024071.wx success!
/Users/<用戶名>/Library/Application Support/微信web開發者工具/Weappdest/1484724024071.wx
就是構建完成的小程序代碼!趕忙去看看!
興致勃勃的找到/Users/<用戶名>/Library/Application Support/微信web開發者工具/Weappdest/
目錄,而後發現:空空如也!
看來微信團隊仍是很謹慎的,在將小程序源碼上傳以後便會刪除構建產出的文件。可是這點小伎倆難不倒程序員!任何行爲都是程序執行的,咱們直接修改相關的程序代碼就能夠了嘛!
在Content/Resources/app.nw/dist/weapp/commit/upload.js
中有一段這樣的代碼:
const a = require('fs'), j = require('rmdir'); //省略無關代碼 _exports.uploadForTest = (l, m, n) => { //省略無關代碼 c(l, { noCompile: !0 }, (s, t) => { if (s) return void n(s.toString()); let u = d.join(k, `${+new Date}.wx`); b(t, u, (v, w) => { j(t, (A, B, C) => {}); //省略無關代碼 if (y > q) return a.unlink(u, () => {}), void n(`代碼包大小爲 ${y} kb,超出限制 ${y-q} kb,請刪除文件後重試`); //省略無關代碼 })
上述代碼省略了一些與咱們當前討論內容無關的代碼,感興趣的讀者能夠自行研究。
上述代碼有兩個刪除文件的行爲:
rmdir
:刪除構建完成可是並未打包的代碼目錄;fs.unlink
:刪除打包完成的文件。將執行刪除的代碼註釋之後,再經過小程序開發者工具進行預覽上傳操做後,在上文中咱們獲得的目錄中便會留下構建以及打包後的文件了。以下:
其中以.wx
爲後綴的文件是通過打包後的文件,也就是上傳到微信服務器的文件。其同名的目錄文件夾是構建完成且打包以前的源文件。
以config.js
爲例,構建後的代碼以下:
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); exports.default = { basePath: 'https://djtest.cn', fileBasePath: 'https://djtest.cn' };
其實僅僅將ES6的語法轉譯成了ES5語法。其他的wxml、wxss以及js文件基本也是這樣的狀態,因此能夠推斷源碼上傳至微信服務器後會執行真正的構建動做,開發工具只執行了一些簡單地構建行爲。
雖然筆者並未從這份代碼中獲得所有的真相,但但願這篇文章可以給後續的探索者提供一些微薄的幫助。