Taro 3.1.0 源码分析
@tarojs/taro
import Taro, { useDidShow } from '@tarojs/taro'
我们用的最频繁的包就是 @tarojs/taro
// taro/index.js
const { CurrentReconciler } = require('@tarojs/runtime')
const taro = require('@tarojs/api').default
if (typeof CurrentReconciler.initNativeApi === 'function') {
CurrentReconciler.initNativeApi(taro)
}
module.exports = taro
module.exports.default = module.exports
// taro-runtime/reconciler.ts
export const CurrentReconciler: Reconciler = Object.assign({
getLifecyle (instance, lifecyle) {
return instance[lifecyle]
},
getPathIndex (indexOfNode) {
return `[${indexOfNode}]`
},
getEventCenter (Events) {
return new Events()
}
}, defaultReconciler)
// shared/utils.ts
export const defaultReconciler = {}
export function mergeReconciler (hostConfig) {
Object.assign(defaultReconciler, hostConfig)
}
// taro-weapp/src/runtime/ts
import { mergeReconciler, mergeInternalComponents } from '@tarojs/shared'
import { hostConfig, components } from './runtime-utils'
mergeReconciler(hostConfig)
mergeInternalComponents(components)
Taro 根据不同的编译环境变量,引入了对应的编译包。
编译包引入的是一个 initNativeAPI
初始化函数,用于初始化对应平台的原生 API。
@tarojs/taro-weapp
微信小程序平台initNativeApi
所做的事情就是将微信的 API 进行一些二次封装,然后转成挂载在 Taro 对象下,开发者调用 Taro 的 API 即可调用到微信官方 API。
export function initNativeApi (taro) {
processApis(taro, wx, {
noPromiseApis,
needPromiseApis
})
taro.cloud = wx.cloud
}
processApis
收集了当前运行平台的 _noPromiseApis
、_needPromiseApis
,将_needPromiseApis
的api Promise 化,都绑定到Taro对象上。
request
processApis
也做了Taro.request 请求改造,将Taro.request 绑定 new taro.Link
/**
* 挂载常用 API
* @param taro Taro 对象
* @param global 小程序全局对象,如微信的 wx,支付宝的 my
*/
function equipCommonApis (taro, global, apis: Record = {}) {
...
// request & interceptors
const request = apis.request ? apis.request : getNormalRequest(global)
function taroInterceptor (chain) {
return request(chain.requestParams)
}
const link = new taro.Link(taroInterceptor)
taro.request = link.request.bind(link)
taro.addInterceptor = link.addInterceptor.bind(link)
taro.cleanInterceptors = link.cleanInterceptors.bind(link)
taro.miniGlobal = global
}
// taro-api/interceptor/index.js
export default class Link {
constructor (interceptor) {
this.taroInterceptor = interceptor
this.chain = new Chain()
}
request (requestParams) {
this.chain.interceptors = this.chain.interceptors.filter(interceptor => interceptor !== this.taroInterceptor)
this.chain.interceptors.push(this.taroInterceptor)
return this.chain.proceed({ ...requestParams })
}
addInterceptor (interceptor) {
this.chain.interceptors.push(interceptor)
}
cleanInterceptors () {
this.chain = new Chain()
}
}
到这里,@tarojs/taro 就已经解析完成了