因为近期使用到 Taro 编写小程序,出于好奇,准备研读一下 Taro 的源码。
目录分析
首先从官网拉取最新的 Taro 源码,版本号为 3.0.18
,源码目录如下:
目录没什么特别的,我们来重点关注一下 packages
目录中的核心包(如下图)
这些核心包构成了 Taro
,实现了 Taro
的多平台构建。
@tarojs/taro
在开发过程中,我们用的最频繁的包就是 tarojs/taro
,我们从入口文件 packages/taro/index.js
开始分析(如下图)
从上图我们可以看出,Taro 根据不同的编译环境变量,引入了对应的编译包,从而加快编译速度,减小编译体积。
编译包引入的是一个 initNativeAPI
初始化函数,用于初始化对应平台的原生 API。
微信平台编译包
这里我们以最流行的微信小程序来举例说明,打开文件 packages/taro/apis/wx.js
,发现了导出的 initNativeAPI
函数(如下图)
我们来对 initNativeApi
所做的事情进行分析,总的来说 initNativeApi
所做的事情就是将微信的 API 进行一些二次封装,然后转成挂载在 Taro 对象下,开发者调用 Taro 的 API 即可调用到微信官方 API。
processApis
我们先来看看 initNativeApi
中的 processApis
方法做了哪些事情吧(如下图)。
从上图可以看出,Taro 首先收集了三类方法:
1. `onAndSyncApis`:事件监听和同步事件 API;
2. `noPromiseApis`:没有返回 `Promise` 的异步事件,`Taro` 将会把这些事件使用 `Promise` 进行二次封装;
3. `otherApis`:其他 API,如设备、媒体、平台专属 API;
对于微信端不支持的方法,将返回一个警告函数(如下图)
对于 otherApis
,如果最后一个参数是 TaroComponent
,则会将最后一个参数替换为 TaroComponent.$scope
(如下图)
对于 onAndSyncApis
和 noPromiseApis
则有几种不同的处理方式:
1. 当第一个参数为字符串时,返回微信 API 执行结果(如下图)
2. 当方法为跳转类函数时,先去掉开头的 `/`,去掉 `query` 部分,使用 url 获取组件。如果组件存在且包含 `componentWillPreload` 方法时,会执行 `componentWillPreload` 并且将执行结果存储在 `cacheData` 中,提供给组件后续的生命周期钩子使用。
3. 新建 `Promise`,将方法封装,在执行成功时 `resolve`,执行失败时 `reject`,然后将该 `Promise` 返回。
上面这些工作就是 processApis
所做的事情,它将所有的微信原生 API 进行二次封装,然后挂载在 Taro 对象中。
request
接下来我们看看对网络请求的改造,这里除了改造 request
外,还新增了 addInterceptor
和 cleanInterceptors
方法,用于在请求发出前或发出后做一些额外操作。代码实现如下:
taro.request = link.request.bind(link)
taro.addInterceptor = link.addInterceptor.bind(link)
taro.cleanInterceptors = link.cleanInterceptors.bind(link)
想要看懂 addInterceptor
的实现,需要找到 Link
的实现(如下图)
从上图红圈处可以看出,用于创建 Link
实例的拦截器将被放在调用链的最后一个,然后由 Chain
依次顺序执行每一个拦截器(interceptor),然后最终执行到创建 Link
实例的这个 interceptor
。
从上面的分析就能很清晰的看出 拦截器
的实现,现在我们来看看 request
的实现(如下图)。
从上图可以看出,request
实现的主要需求就是将原生的 request
方法使用 Promise
进行二次封装,并没有更多特殊处理。
经过分析,我们发现 Taro 对网络请求的封装,使其拥有了 拦截器
的特性,并且有了更友好的 Promise
调用方式。
其他
接下来三个都是微信小程序的全局方法,直接进行挂载(如下图)
接下来是像素转换函数,主要是将像素转成对应的 rpx
(如下图)
紧随其后的是 canIUseWebp
,意思是判断是否可以使用 webp
格式的图片(如下图)
从下图可以看出,目前只有安卓平台和开发者工具支持 webp
格式的图片,所以 webp
格式的图片一定要谨慎使用。
最后一步,将微信的云开发 SDK 挂载在 Taro.cloud
对象中,完成挂载(如下图)
小结
到这里,@tarojs/taro
就已经解析完成了,这部分源码的实现还是比较简洁明了的,作为 Taro
源码阅读系列入门还是挺不错的~
最后一件事
如果您已经看到这里了,希望您还是点个赞再走吧~
您的点赞是对作者的最大鼓励,也可以让更多人看到本篇文章!
如果觉得本文对您有帮助,请帮忙在 github 上点亮 star
鼓励一下吧!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。