编译时使用 babel-parser 将 Taro 代码解析成抽象语法树,然后通过 babel-types 对抽象语法树进行一系列修改、转换操作,最后再通过 babel-generate 生成对应的目标代码。
缺点:
Taro 3 主要通过在小程序端模拟实现 DOM、BOM API 来让前端框架直接运行在小程序环境中,从而达到了小程序和 H5 统一的目的。 而对于生命周期、组件库、API、路由等差异,依然可以通过定义统一标准,各端负责各自实现的方式来进行抹平。 所以,在 Taro 3 中同时支持 React、Vue 等框架,还支持让开发者自定义去拓展其他框架的支持。
Taro 3 之后,小程序端的整体架构。首先是用户的 React 代码会通过 cli 进行 webpack 打包,其次会在运行时提供 React 对应的适配器进行适配,然后调用 Taro 提供的 DOM 和 BOM API,最后把整个程序渲染到所有的小程序端上面。
React-DOM 包含大量浏览器兼容类的代码,导致包太大,而这部分并不需要,因此做了一些定制和优化。
React 16+ 的架构:最上层是 React 的核心部分 react-core,中间是 react-reconciler,其职责是 维护 虚拟 DOM 树,内部实现了 Diff/Fiber 算法,决定更新时间和更新内容。 Renderer 负责具体平台的渲染工作,提供宿主组件、处理事件等等。
Taro 实现了 taro-react 包,用来连接 react-reconciler 和 taro-runtime 的 BOM/DOM API。是基于 react-reconciler 的小程序专用 React 渲染器,连接 @tarojs/runtime 的 DOM 实例,相当于小程序版的 react-dom。
最后,React 代码运行会生成 Taro DOM Tree,那么 如何更新到页面上呢?
小程序并没有提供动态创建节点的能力,需要考虑如何使用相对静态的 wxml 来渲染相对动态的 Taro DOM Tree。 Taro 使用了 模版拼接的方式,根据运行时提供的 DOM 树数据结构,各 templates 递归地相互引用,最终渲染出对应的动态 DOM 树。
首先,将小程序的所有组件进行模版化处理,从而得到小程序组件对应的模版。需要在 template 里面写上 组件 如 view,把它所有的属性全部列出来(因为小程序里面不能动态的添加属性)。 接下来遍历渲染所有子节点,基于组件的 template,动态递归渲染整棵树。
具体流程为 先遍历 Taro DOM Tree 根节点的子元素,再根据每个子元素的类型选择对应的模版来渲染子元素,然后在每个模版中又会去遍历当前元素的子元素,以此把整个节点数递归遍历出来。
Taro 以小程序为主,因此 在 H5 端实现了一套基于小程序规范的组件库和 API 库。
H5 端架构,同样的需要把用户的 React 代码通过 Webpack 打包,然后在运行时做三件事: