V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
faywong8888
V2EX  ›  微信

浅析微信小程序之 IDE

  •  
  •   faywong8888 · 2017-01-18 15:49:00 +08:00 · 6294 次点击
    这是一个创建于 2648 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我在上一篇纠正对微信小程序的一个认知中提到现在的微信小程序是 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 转换,可读性很差。我取其精华,梳理出一些重点逻辑。

    • wxml2html

    这个步骤是把本地 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

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

    • 小程序安装包的格式

    小程序格式 小程序格式 html 部分 小程序格式 dom 部分

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

    • 项目->预览

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

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

    6 条回复    2017-01-19 10:21:34 +08:00
    suinia
        1
    suinia  
       2017-01-18 16:46:44 +08:00
    本地客户端肯定用 html 。关键是在小程序端好像没有什么分析
    grayon
        2
    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
        3
    s546360316  
       2017-01-18 17:40:48 +08:00
    图片不见了,楼主
    chemzqm
        4
    chemzqm  
       2017-01-18 18:07:32 +08:00
    这个 formatDate 函数怎么跟我写的一模一样?
    faywong8888
        5
    faywong8888  
    OP
       2017-01-18 20:07:03 +08:00
    @s546360316 哈哈。我是先 google 了下, v 友说发图用 [路过图床]( https://imgchr.com/) 好使,然后我就信了。
    faywong8888
        6
    faywong8888  
    OP
       2017-01-19 10:21:34 +08:00 via iPhone
    @suinia 看下 wxml2js 的输出, gist 的链接,这就是在小程序端跑的 js 代码。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2860 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 13:48 · PVG 21:48 · LAX 06:48 · JFK 09:48
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.