4

因为近期使用到 Taro 编写小程序,出于好奇,准备研读一下 Taro 的源码。

目录分析

首先从官网拉取最新的 Taro 源码,版本号为 3.0.18,源码目录如下:

image

目录没什么特别的,我们来重点关注一下 packages 目录中的核心包(如下图)

image

这些核心包构成了 Taro,实现了 Taro 的多平台构建。

@tarojs/taro

在开发过程中,我们用的最频繁的包就是 tarojs/taro,我们从入口文件 packages/taro/index.js 开始分析(如下图)

image

从上图我们可以看出,Taro 根据不同的编译环境变量,引入了对应的编译包,从而加快编译速度,减小编译体积。

编译包引入的是一个 initNativeAPI 初始化函数,用于初始化对应平台的原生 API。

微信平台编译包

这里我们以最流行的微信小程序来举例说明,打开文件 packages/taro/apis/wx.js,发现了导出的 initNativeAPI 函数(如下图)

image

我们来对 initNativeApi 所做的事情进行分析,总的来说 initNativeApi 所做的事情就是将微信的 API 进行一些二次封装,然后转成挂载在 Taro 对象下,开发者调用 Taro 的 API 即可调用到微信官方 API。

processApis

我们先来看看 initNativeApi 中的 processApis 方法做了哪些事情吧(如下图)。

image

从上图可以看出,Taro 首先收集了三类方法:

1. `onAndSyncApis`:事件监听和同步事件 API;
2. `noPromiseApis`:没有返回 `Promise` 的异步事件,`Taro` 将会把这些事件使用 `Promise` 进行二次封装;
3. `otherApis`:其他 API,如设备、媒体、平台专属 API;

对于微信端不支持的方法,将返回一个警告函数(如下图)

image

对于 otherApis,如果最后一个参数是 TaroComponent,则会将最后一个参数替换为 TaroComponent.$scope(如下图)

image

对于 onAndSyncApisnoPromiseApis 则有几种不同的处理方式:

1. 当第一个参数为字符串时,返回微信 API 执行结果(如下图)

image

2. 当方法为跳转类函数时,先去掉开头的 `/`,去掉 `query` 部分,使用 url 获取组件。如果组件存在且包含 `componentWillPreload` 方法时,会执行 `componentWillPreload` 并且将执行结果存储在 `cacheData` 中,提供给组件后续的生命周期钩子使用。

image

3. 新建 `Promise`,将方法封装,在执行成功时 `resolve`,执行失败时 `reject`,然后将该 `Promise` 返回。

image

上面这些工作就是 processApis 所做的事情,它将所有的微信原生 API 进行二次封装,然后挂载在 Taro 对象中。

request

接下来我们看看对网络请求的改造,这里除了改造 request 外,还新增了 addInterceptorcleanInterceptors 方法,用于在请求发出前或发出后做一些额外操作。代码实现如下:

  taro.request = link.request.bind(link)
  taro.addInterceptor = link.addInterceptor.bind(link)
  taro.cleanInterceptors = link.cleanInterceptors.bind(link)

想要看懂 addInterceptor 的实现,需要找到 Link 的实现(如下图)

image

从上图红圈处可以看出,用于创建 Link 实例的拦截器将被放在调用链的最后一个,然后由 Chain 依次顺序执行每一个拦截器(interceptor),然后最终执行到创建 Link 实例的这个 interceptor

从上面的分析就能很清晰的看出 拦截器 的实现,现在我们来看看 request 的实现(如下图)。

image

从上图可以看出,request 实现的主要需求就是将原生的 request 方法使用 Promise 进行二次封装,并没有更多特殊处理。

经过分析,我们发现 Taro 对网络请求的封装,使其拥有了 拦截器 的特性,并且有了更友好的 Promise 调用方式。

其他

接下来三个都是微信小程序的全局方法,直接进行挂载(如下图)

image

接下来是像素转换函数,主要是将像素转成对应的 rpx(如下图)

image

紧随其后的是 canIUseWebp,意思是判断是否可以使用 webp 格式的图片(如下图)

image

从下图可以看出,目前只有安卓平台和开发者工具支持 webp 格式的图片,所以 webp 格式的图片一定要谨慎使用。

最后一步,将微信的云开发 SDK 挂载在 Taro.cloud 对象中,完成挂载(如下图)

image

小结

到这里,@tarojs/taro 就已经解析完成了,这部分源码的实现还是比较简洁明了的,作为 Taro 源码阅读系列入门还是挺不错的~

最后一件事

如果您已经看到这里了,希望您还是点个赞再走吧~

您的点赞是对作者的最大鼓励,也可以让更多人看到本篇文章!

如果觉得本文对您有帮助,请帮忙在 github 上点亮 star 鼓励一下吧!

personal


晒兜斯
1.8k 声望534 粉丝