微信小程序 devtool隐藏的秘密


Posted in Javascript onJanuary 21, 2017

微信小程序 devtool

笔者参与的小程序项目开发也进入尾声了,坑也踩得七七八八,对于哪些没有涵盖和深入使用的功能笔者就不班门弄斧了。

前几篇文章讲了那么多细节也好,策略也好,都是应用层面的东西。自微信小程序公布以来就有先行者不断的探索小程序背后的运行机制。小程序的开发语法和API与前端工程师熟悉的html/js/css非常相似,所以会令很多人疑惑小程序与普通的HTML5应用到底有什么区别。这篇文章其实将小程序的基本运行机制剖析的差不多了,简单概括就是:

  • 大部分内容会转化为常规的html/css/js,并使用webview渲染;
  • 部分组件调用native实现功能。

既然已经有先行者得出了结论,为啥还要写这篇文章呢?当然是为了凑齐七篇啦,哈哈哈...

开玩笑!这篇文章的目的不是重复别人的结论,而是将笔者研究小程序开发工具源码的一些心得和结论记录下来,以方便大家后续更深入的探索。

看看devtool的源码有什么

第一步是找到小程序devtool的源码,以mac系统为例,源码的打开方式如下图:

微信小程序 devtool隐藏的秘密

其他的文件不用理会,我们要研究的主要代码在Content/Resources/app.nw/dist目录下,这个目录包括devtool的功能代码以及对小程序进行执行、编译、打包、上传等功能的代码。当然,这些代码都是经过混淆的,读起来还挺费劲(摊手~

需要着重注意的是Content/Resources/app.nw/dist/weapp目录,以及commit和trans两个子目录:

微信小程序 devtool隐藏的秘密

从文件的命名上大致可以猜到每个文件对应的功能:

  • trans目录下的文件负责将小程序源码进行一系列的转换,最终被转换为浏览器可识别的html、css以及js;
  • commit目录下的文件负责执行小程序的构建、打包、上传等功能。

既然我们知道小程序会进行构建打包流程,想得知小程序运行机制最好的办法就是研究构建完毕之后的代码。有了这个目标之后,下一步就是查看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隐藏的秘密

上传小程序的流程打包后的小程序在哪里

找到日志文件后便可以从devtool的执行日志中获取小程序被构建后的代码存放位置。当然,第一步是要讲小程序进行构建,操作方法是在小程序开发工具的“项目”菜单”中点击”预览“:

微信小程序 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:删除打包完成的文件。

将执行删除的代码注释以后,再通过小程序开发者工具进行预览上传操作后,在上文中我们得到的目录中便会留下构建以及打包后的文件了。如下:

微信小程序 devtool隐藏的秘密

其中以.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文件基本也是这样的状态,所以可以推断源码上传至微信服务器后会执行真正的构建动作,开发工具只执行了一些简单地构建行为。

虽然笔者并未从这份代码中得到全部的真相,但希望这篇文章能够给后续的探索者提供一些微薄的帮助。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

Javascript 相关文章推荐
用javascript实现计算两个日期的间隔天数
Aug 14 Javascript
JQuery 动画卷页 返回顶部 动画特效(兼容Chrome)
Feb 15 Javascript
浅析jQuery中常用的元素查找方法总结
Jul 04 Javascript
Web打印解决方案之证件套打的实现思路
Aug 29 Javascript
jQuery如何跳转到另一个网页 就这么简单
Dec 28 Javascript
JS实现隔行换色的表格排序
Mar 27 Javascript
Angular2 父子组件数据通信实例
Jun 22 Javascript
用node撸一个监测复联4开售短信提醒的实现代码
Apr 10 Javascript
解决layui的radio属性或别的属性没显示出来的问题
Sep 26 Javascript
利用JS如何获取form表单数据
Dec 19 Javascript
基于JavaScript实现控制下拉列表
May 08 Javascript
Vue实现穿梭框效果
Sep 30 Javascript
JS设置CSS样式的方式汇总
Jan 21 #Javascript
JS 实现 ajax 异步浏览器兼容问题
Jan 21 #Javascript
RequireJS 依赖关系的实例(推荐)
Jan 21 #Javascript
js操作浏览器的参数方法
Jan 21 #Javascript
JS实现图片高斯模糊切换效果的焦点图实例
Jan 21 #Javascript
js实现用户输入的小写字母自动转大写字母的方法
Jan 21 #Javascript
jQuery点击弹出层弹出模态框点击模态框消失代码分享
Jan 21 #Javascript
You might like
PHP高级编程实例:编写守护进程
2014/09/02 PHP
php + WebUploader实现图片批量上传功能
2019/05/06 PHP
使用CSS和jQuery模拟select并附提交后取得数据的代码
2013/10/18 Javascript
jquery、js操作checkbox全选反选
2014/03/12 Javascript
JQuery创建DOM节点的方法
2015/06/11 Javascript
jquery获取多个checkbox的值异步提交给php
2015/07/07 Javascript
javascript实现鼠标移到Image上方时显示文字效果的方法
2015/08/07 Javascript
javascript多物体运动实现方法分析
2016/01/08 Javascript
bootstrapfileinput实现文件自动上传
2016/11/08 Javascript
简单的JS控制button颜色随点击更改的实现方法
2017/04/17 Javascript
JS实现的JSON序列化操作简单示例
2018/07/02 Javascript
如何通过JS实现转码与解码
2020/02/21 Javascript
electron 如何将任意资源打包的方法步骤
2020/04/16 Javascript
JS如何实现手机端输入验证码效果
2020/05/13 Javascript
JavaScript组合设计模式--改进引入案例分析
2020/05/23 Javascript
浅谈vue中$event理解和框架中在包含默认值外传参
2020/08/07 Javascript
[01:02:38]DOTA2-DPC中国联赛定级赛 LBZS vs Phoenix BO3第二场 1月10日
2021/03/11 DOTA
[47:43]完美世界DOTA2联赛PWL S3 Magama vs GXR 第二场 12.19
2020/12/24 DOTA
Python访问MySQL封装的常用类实例
2014/11/11 Python
详解Django中间件的5种自定义方法
2018/07/26 Python
python实现获取单向链表倒数第k个结点的值示例
2019/10/24 Python
使用python-opencv读取视频,计算视频总帧数及FPS的实现
2019/12/10 Python
Python pygame绘制文字制作滚动文字过程解析
2019/12/12 Python
Django框架配置mysql数据库实现过程
2020/04/22 Python
Django自定义YamlField实现过程解析
2020/11/11 Python
英国排名第一的最新设计师品牌手表独立零售商:TIC Watches
2016/09/24 全球购物
巴黎卡诗美国官方网站:始于1964年的头发头皮护理专家
2017/07/10 全球购物
Bibloo荷兰:女士、男士和儿童的服装、鞋子和配饰
2019/02/25 全球购物
酒店服务实习自我鉴定
2013/09/22 职场文书
五星级酒店餐饮部总监的标准岗位职责
2014/02/17 职场文书
2014年街道办事处工作总结
2014/12/11 职场文书
师德先进个人材料
2014/12/20 职场文书
高中教师个人总结
2015/02/10 职场文书
解析CSS 提取图片主题色功能(小技巧)
2021/05/12 HTML / CSS
Ubuntu18.04下QT开发Android无法连接设备问题解决实现
2022/06/01 Java/Android
win10壁纸在哪个文件夹 win10桌面背景图片文件位置分享
2022/08/05 数码科技