# 前言

这一章节中我们将对渲染层的底层基础库WAWebview.js进行一个分析,看看里面都有哪些模块。

本章内容分解:

  • 渲染层基础库源码解析
  • Exparser系统源码解析。

# WAWebview.js注入

我们重温一下在哪里看到过渲染层基础库的注入。在最开始章节找寻小程序渲染层代码中我们找寻到了渲染层基础库的注入:

image.png

# 模块分析

首先我们进行WAWebview.js文件的解析。在我们2.17.3版本的基础库包中,渲染层基础库代码大概有8万多行。那么我们怎么进行分析呢?

我这边使用了比较传统的方法,就是折叠法,折叠成代码块,然后进行分析。这里折叠使用了Subline编辑器,因为我的VsCode插件较多,每次修改或者变动文件会有点卡,使用没有插件的Subline比较轻量,如果你也是跟着这本小册同步的去做,建议你也下载一个Subline去折叠代码。

我们从上往下进行分析,第一个模块是Foundation模块。

# core-js模块

最开始有一段4000多行的模块,为core-js模块。

image.png

core-js负责初始化框架js代码,编译js,加载业务逻辑js等功能。

# Foundation

Foundation是基础模块。我们来看一下声明的核心位置,在文件的4275行左右。

image.png

在源码的基础上我添加了一些备注,方便阅读理解。本身是没有备注的。

我们可以从其中看到里面包含了一些api,有EventEmitter事件的发布订阅,配置的Ready事件,基础库Ready事件,Bridge Ready事件,env、global环境变量。

其中EventEmitter 的核心就是事件触发与事件监听器功能的封装。小程序应该是自己在内部实现了一套。如果你想自己尝试一下Node.js环境下可以使用require('events')包,js环境下也有类似的实现event-emitter (opens new window),值得了解一下。

# WeixinJSBridge

WeixinJSBridge通讯模块,在4528行左右的。

image.png

可以看到WeixinJSBridge通讯模块中包含了我们在通讯系统章节讲解的通讯api,包含有on、publish、invoke、subscribe、invokeCallbackHandler、subscribeHandler。

通讯系统的具体实现在通讯系统章节有讲解,这里只是对Native注入通讯api的封装,便于内部调用。

# 异常监听模块

基础库内针对promise或者js等异常事件也是做了监听处理。在文件4872行左右

image.png

# 日志打印模块

日志打印模块在文件5027行左右。

image.png

日志打印模块包含wxNativeConsole、__webviewConsole__、wxConsole、wxPerfConsole等,打印日志类型非常丰富。日志打印API在基础库源码中导出充斥着,因为边界函数特别的多,恨不得每个逻辑判断都加上try catch

# 系统函数和第三方函数模块

系统函数和第三方函数模块在文件5294行左右。

image.png

# Report信息上报模块

Report信息上报模块在文件5488行左右。内部包含了非常多种类的上报api及异常监听api。

image.png

# Exparser模块

Exparser组件系统模块的实现就是在基础库中,文件9820行左右。

image.png

还记得exparser组件系统章节中渲染层经过编译后的自定义HTML标记吗?忘记没关系,我们回顾一下

image.png

上图是渲染层中编译后的Exparser自定义组件标记,wx-text、wx-view等。我们在WXML中写的结构是这样的:

image.png

这是经过几层编译后的结果,前面章节我们讲到 WXML文件经过WCC编译器编译成js文件,生成$gwx()函数, $gwx()函数接收文件路径和动态数据生成virtualDOM。这里看一下编译后的virtualDOM中的<text>标记。

image.png

可以看到virtualDOM中已经把WXML中的<text>标记编译成了wx-text,通过Exparser组件系统章节我们可知这是Exparser自定义组件。

那么Exparser组件系统就是将virtualDOM转化成HTML自定义标记的最后环节。

顺着上面的线索我们看一下渲染层基础库Exparser模块中的wx-text这个组件的定义是什么样的。为了方便讲解我把代码进行了拆分,我们按照模块逐一分解。

首先进行元素的注册,并且声明模版template。

image.png

与WebComponent中的tempalte一致,并且设计了插槽slot。

image.png

接下来就是可配置的一些属性,并且这些属性是开放出去的。与小程序组件文档上的属性进行对应。

image.png

接下里就是方法模块:

image.png

可以看到method里面就是自定义的一些方法, 其中_htmlDecode处理了space的合法值及一些语法的转换实现,对应文档中的:

image.png

文档中tips描述的也很明确。

可以看到与method同层级的还有created、attached方法,其中attached为组件扩展附加方法,比如给予一些提示或者边界检测。上面截图中的attached方法内部包含一条警告日志:

对于开发人员:[text] selectable已弃用,请改用user select。

created方法即为初始化组件方法,内部触发method._update函数,那我们就看一下_update方法内部:

image.png

内部实现首先是判断文本在不可选的状况,纯展示文本如果过长那么提示

For developer: 提示: text 组件包含了长文本,可以考虑增加 user-select 属性,方便用户复制。

然后就是进行上面讲到的_htmlDecode方法对文本进行一些转译处理,最后插入到slot插槽中去。

这样的话一个完整的wx-text类型的exparser组件就注册完成了。

# virtualDOM模块

VirtualDOM 模块和Vue、React中virtualDOM实现相似,但这里它主要模拟了DOM 接口上面的element() 对象,在文件78322行左右。

image.png

截图是此模块中关于元素样式属性的配置。

# 默认样式注入模块

最后的模块就是默认样式注入,在文件83694行左右。

image.png

# 总结

这一章节分析了渲染层基础库WAWebview的模块分析。下一节我们进行逻辑层基础库WAService的模块分析。

阅读全文