由于近期使用到 Taro 编写小程序,出于好奇,准备研读一下 Taro 的源码。git
首先从官网拉取最新的 Taro 源码,版本号为 3.0.18
,源码目录以下:github
目录没什么特别的,咱们来重点关注一下 packages
目录中的核心包(以下图)web
这些核心包构成了 Taro
,实现了 Taro
的多平台构建。小程序
在开发过程当中,咱们用的最频繁的包就是 tarojs/taro
,咱们从入口文件 packages/taro/index.js
开始分析(以下图)微信小程序
从上图咱们能够看出,Taro 根据不一样的编译环境变量,引入了对应的编译包,从而加快编译速度,减少编译体积。api
编译包引入的是一个 initNativeAPI
初始化函数,用于初始化对应平台的原生 API。微信
这里咱们以最流行的微信小程序来举例说明,打开文件 packages/taro/apis/wx.js
,发现了导出的 initNativeAPI
函数(以下图)markdown
咱们来对 initNativeApi
所作的事情进行分析,总的来讲 initNativeApi
所作的事情就是将微信的 API 进行一些二次封装,而后转成挂载在 Taro 对象下,开发者调用 Taro 的 API 便可调用到微信官方 API。网络
咱们先来看看 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
外,还新增了 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
鼓励一下吧!