# 前言
前一章节我们看到了WXSS文件编译后的源码,没有错WXML文件业务要进行编译步骤,这一章节就带大家一步一步刨析WXML编译后的源码。
# WXML
第一步,跟WXSS章节一样,去寻找用于编译WXML文件的可以执行文件WCC。
在微信开发者工具控制台中,执行openVender()。

可以看到就在WXCS上边就是WCC可执行文件。我们还是一样的操作。把WCC可执行文件拷贝到pages/logs目录下面,如下图所示。

WCC可执行文件的具体使用命令可以通过--help查看到。

执行命令$ ./wcc -d logs.wxml >> wxml.js

可以看到pages/logs目录下多了一个wxml.js文件,这个就是编译之后的js文件,我们来看一下里面的具体结构。

这部分代码不像WXSS编译出来的代码可以直接观看,而是进行了压缩混淆。基本上是不可读的。但是我们还是可以一点一点去分析这到底是怎么运行的,我们继续往下看。
可以看出,整体代码结构就是一个函数,函数名称为$gwx。它的作用是生成虚拟dom树,用于渲染真实节点。内部还有一些边界函数。比如有意思的 _n函数里面包含一个提示:

英文的意思是超出Dom限制,请检查是否有任何错误,DOM数量不可以超过16000个。但是比较之前的版本,这个提示可没有这么友好,它是这个样子的:

汉译我就不放在这里了哈哈,有兴趣的自己翻译一下,我们继续。
但是这个时候我们只知道$gwx是个函数,但是怎么调用呢?继续去渲染层代码中进行寻找。还是打开渲染层控制台Elements中,control + F 进行寻找即可,首先我们可以看到编译后的函数在渲染层也有一套。如下图:

可以看到编译后的WXML文件以js的形式插入到了渲染层的<script>标签中。对比WXSS编译后用eval执行还是有区别的。
但是在这个script标签中插入了$gwx函数之后并没有执行这个函数。我们继续查找,看看$gwx函数是在哪里执行的,并且需要传入哪些参数。

在渲染层继续查找就找到了$gwx函数执行的地方,我们提取出来看一下。
var decodeName = decodeURI("./pages/index/index.wxml")
var generateFunc = $gwx(decodeName)
这时候就知道了$gwx函数的参数正是WXML文件的业务路径。如上图是在。这里注意一下,为了后方讲解顺利,我们把WCC执行文件放在了pages/logs目录下,所以我们这里传入$gwx函数的路径是./pages/logs/logs.wxml。
我们在渲染层的控制台中执行一下$gwx函数并传入参数。

可以看到执行$gwx函数后的返回值generateFunc也是一个函数。我们再次执行这个函数,看一下返回值。

generateFunc函数的返回值是一颗树状结构,就是该页面wxml对应的js对象形式表示的dom树。
那为什么$gwx函数不直接返回虚拟DOM树呢,而是先返回generateFun?是因为需要注入动态数据。再看一下编译前的WXML文件结构。

可以看到内部需要动态接受几个变量
- logs 是一个数组
- log 是个字符串
- index 循环索引
generateFunc函数在执行的时候需要动态注入这些数据,我们手动注入一些假数据看一下生成出来的虚拟DOM树与前面没有注入数据的有什么区别。

