携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第7天,点击查看活动详情
前言
上一篇文章分享了Taro3编译H5端会出现部分api缺少的问题,同时也讲述了我的解决方案,这里我们就这个问题进行深入的探究一下。
工具
- Taro源码 3.3.19
- vscode
源码探究
这里我不过多关注Taro在webpack编译时,runner中发生了什么,只关注有关api相关的细节实现。
首先,Taro3的所有端的api的入口都是基于@tarojs/taro。这这里抛出了Taro对象,所以才可以通过Taro来直接获取api进行使用。
const { container, SERVICE_IDENTIFIER } = require('@tarojs/runtime')
const taro = require('@tarojs/api').default
...
module.exports = taro
module.exports.default = module.exports
通过这里,我们可以发现,taro在这里只是做了个简单的导入导出操作,真正的taro是从@tarojs/api文件中导出的。接下来,我们就直接进入package/taro-api文件夹下,直接找到入口文件index.js查看代码,核心部分大致是这样的:
const Taro = {
Behavior,
getEnv,
ENV_TYPE,
Link,
interceptors,
Current,
getCurrentInstance,
options,
nextTick,
eventCenter,
Events,
useDidShow,
useDidHide,
usePullDownRefresh,
useReachBottom,
usePageScroll,
useResize,
useShareAppMessage,
useTabItemTap,
useTitleClick,
useOptionMenuClick,
usePullIntercept,
useShareTimeline,
useAddToFavorites,
useReady,
useRouter,
getInitPxTransform
}
Taro.initPxTransform = getInitPxTransform(Taro)
Taro.preload = getPreload(Current)
Taro.pxTransform = getPxTransform(Taro)
export default Taro
通过这里我们基本就初步找到了Taro导出api的地方了,而且通过这段代码可以确认到为什么之前的问题。这部分api是字啊这里重新定义固定导出的,其余的api是根据不同的端做了兼容处理,然后挂载到Taro对象上的。所以我们碰到的Taro报错,部分api缺少的问题,就是出现在这里,h5端的那部分api没有成功挂载上去。
恰好,经过一番寻找,我在Taro的官方文档中找到了佐证:
在 H5 环境,
@tarojs/taro
会从@tarojs/api
取与平台无关的 API,从@tarojs/taro-h5
中取遵循小程序规范实现的 API,最终集合成一个 Taro 对象暴露给开发者
经过一番搜索查找,我们最后锁定了taro-h5文件夹,进入入口文件index.ts之后,我们发现了下面这段代码
import Taro from './api/taro'
export * from './api/index'
export * from './api/taro'
export default Taro
这里导出了一个默认的Taro,是从api文件夹下的taro文件中引入的,另外将index和taro文件中导出的东西做了一次导入导出操作。
探索了一下taro.ts文件,发现跟taro-api文件的入口文件是很相似的,处理的是Taro对象,很可惜,不是我们要找的api。接下来,我们再来看index.ts文件
export * from './ad'
export * from './ai'
export * from './base'
export * from './canvas'
...
export * from './swan'
这个文件中只做了api下文件夹中所有的内容的导入导出,但是看了一下这些文件名,直觉告诉我们这就是我们要找的。我们进入其中一个base文件夹查看一下。
export const canIUse = temporarilyNotSupport('canIUse')
export function arrayBufferToBase64 (arrayBuffer) {
return fromByteArray(arrayBuffer)
}
export function base64ToArrayBuffer (base64) {
return toByteArray(base64)
}
这不就是我们通过Taro获取的api嘛,那就找到了,就是它。找到这里,我们也就理解了为什么会出现部分api缺少的问题了。也就反应过来了,问什么通过解构引入的方式可以解决了。
结语
好了,这里我们就只是简单的探索到这里了,更详细的研究我们后续再深入展开。欢迎大家在下方留言讨论。