浅析微信小程序之 IDE

2017-01-18 15:49:00 +08:00
 faywong8888

我在上一篇纠正对微信小程序的一个认知中提到现在的微信小程序是 h5 做的,那今天呢,接着花十分钟浅谈下小程序 IDE 中的一些逻辑和线索,既能佐证之前的言论,又可以当做今天半天工作的总结。

小程序 IDE 的架构

没什么好说的,网站上整齐地亮着 windows, mac, linux 三个平台的安装包, 90% 的可能性是用的 nwjs,那实际呢,也确实是用的 nwjs 。

main entry 在哪儿

页面启动的入口在哪里呢,我们看下 network 面板:

可见启动流程是 page-frame.html -> appservice 服务下载 asdebug.js 以及其他 js ,比如 appservice 的地址为: http://685122098.appservice.open.weixin.qq.com/asdebug.js

那这是个在线地址吗, no, no, no, 它是个本地代理地址,由 nwjs 后端实现。其中 685122098 是一个 hash ,由你的小程序 appId + name hash 生成。

我们看下这个代理服务器的代理规则:

梳理下重点

由于 IDE 整个的代码量巨大,且大量使用了 JS 的新特性 + minify 转换,可读性很差。我取其精华,梳理出一些重点逻辑。

这个步骤是把本地 wxml 格式的小程序模板转为 html 格式,纳尼,原来真是 html 啊。为了断了你使用原始 html + Dom 操作的念想, IDE 特意禁止展示原始的 html :

附上 wxml2html 过程的输入及输出

输出的 html 代码中包含了微信 js api 的实现,前端 weUI 样式,以及 template -> html 元素的对应。 记性好的老司机肯定记得我曾经说过,有些组件的实现现在是 h5 ,未来可以迁移至用 native 来实现,这一点体现在:

            var m = function() {
                return {
                    renderingMode: "native",
                    keepWhiteSpace: !1,
                    parseTextContent: !1
                }
            };
            g._setGlobalOptionsGetter = function(e) {
                m = e
            };

            // 创建元素的构造器
                        g.create = function(e, t, n, r) {
                var a = m(),
                    s = r.renderingMode || a.renderingMode,
                    c = k;
                "native" === s && (c = E);
                var d = o(e.attributes),
                    u = {
                        parseTextContent: void 0 !== d["parse-text-content"] || r.parseTextContent || a.parseTextContent,
                        keepWhiteSpace: void 0 !== d["keep-white-space"] || r.keepWhiteSpace || a.keepWhiteSpace
                    },
                    h = e.content;
                if ("TEMPLATE" !== e.tagName)
                    for (h = document.createDocumentFragment(); e.childNodes.length;) h.appendChild(e.childNodes[0]);
                var f = !1,
                    v = function(e, o, r, a) {
                        for (var d = void 0, u = 0; u < o.length; u++) {
                            var h = o[u],
                                g = r.concat(e.length);
                            if (8 !== h.nodeType)
                                if (3 !== h.nodeType)
                                    if ("WX-CONTENT" !== h.tagName && "SLOT" !== h.tagName) {
                                        var m = h.tagName.indexOf("-") >= 0 && "native" !== s,
                                            k = null;
                                        m || (k = document.createElement(h.tagName));
                                        var E = "",
                                            S = h.attributes,
                                            T = [];
     ......

在线上版本(真机环境)中运行的代码由 wxml2js 过程生成,怎么验证呢。好,接下来我们讲下小程序安装包的格式:

总结下安装包的格式:紧凑型单文件形式 + html 框架 /容器部分 + 参考 wxml 模板转换得来的 js (动态生成 dom )

涉及到打包并上传的逻辑,夜已深,只能直抒胸臆了:

注:转载请注明本文原始出处blog of faywong

6306 次点击
所在节点    微信
6 条回复
suinia
2017-01-18 16:46:44 +08:00
本地客户端肯定用 html 。关键是在小程序端好像没有什么分析
grayon
2017-01-18 16:52:13 +08:00
https://mp.weixin.qq.com/debug/wxadoc/dev/devtools/details.html

在 iOS 上,小程序的 javascript 代码是运行在 JavaScriptCore 中,是由 WKWebView 来渲染的,环境有 iOS8 、 iOS9 、 iOS10
在 Android 上,小程序的 javascript 代码是通过 X5 JSCore 来解析,是由 X5 基于 Mobile Chrome 37 内核来渲染的
在 开发工具上, 小程序的 javascript 代码是运行在 nwjs 中,是由 Chrome Webview 来渲染的
s546360316
2017-01-18 17:40:48 +08:00
图片不见了,楼主
chemzqm
2017-01-18 18:07:32 +08:00
这个 formatDate 函数怎么跟我写的一模一样?
faywong8888
2017-01-18 20:07:03 +08:00
@s546360316 哈哈。我是先 google 了下, v 友说发图用 [路过图床]( https://imgchr.com/) 好使,然后我就信了。
faywong8888
2017-01-19 10:21:34 +08:00
@suinia 看下 wxml2js 的输出, gist 的链接,这就是在小程序端跑的 js 代码。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/335415

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX