《微信小程序七日谈》系列文章: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文件基本也是这样的状态,因此能够推断源码上传至微信服务器后会执行真正的构建动做,开发工具只执行了一些简单地构建行为。
虽然笔者并未从这份代码中获得所有的真相,但但愿这篇文章可以给后续的探索者提供一些微薄的帮助。