taro v3 引入 taro-ui 3.0.0 版本,编译成 H5,部分组件在处理事件时会报错 _xxx is not defined
以 **AtAccordion ** 组件为例,该组件使用了 Taro.createSelectorQuery 接口,编译成 H5, 点击组件会报错:
`_createSelectorQuery is not defined `。但是编译成功,小程序正常运行。
系统信息
"react": "^16.10.0",
"react-dom": "^16.10.0",
"@tarojs/taro": "3.0.11"
"taro-ui": "3.0.0-alpha.3"
问题解决
经排查,是以下原因导致。
taro-h5 的 createSelectorQuery 等接口其实没有直接挂在 Taro 对象(为了 tree shaking)。
以下代码其实是通过 babel-plugin-transform-taroapi 插件转换了才能正常运行。
import Taro from '@tarojs/taro'
Taro.createSelectorQuery(...)
转换后的代码如下
import Taro { createSelectorQuery as _createSelectorQuery } from '@tarojs/taro'
_createSelectorQuery(...)
babel-plugin-transform-taroapi 插件做两件事情:
- 把
import Taro from '@tarojs/taro'
转换成import Taro, { xxx as _xxx } from
'@tarojs/taro'
- 把
Taro.xxx()
转换成_xxx()
那么错误信息 _xxx is undefined 说明第二步转换成功了,第一步似乎没有成功,导致 _xxx undefined。
继续排查发现是 taro 引入 taro-ui 时使用了 index.umd.js 作为入口文件。
taro 默认的入口顺序为0: `['main:h5', 'browser', 'module', 'main']` [1]
而 taro-ui 3.0.0 的 package.json 中包含了以下几个入口:
"browser": "dist/index.umd.js",
"module": "dist/index.esm.js",
"main": "dist/index.js",
"source": "src/index.ts",
可以看到 index.umd.js 被命中了。
而 index.umd.js 中的 `import Taro from '@tarojs/taro'` 已经被编译成 umd 格式,导致插件找不到 import,无法完成第一步转换。具体细节可以看下这个插件的源码[2]。
临时解决办法
在 taro-ui 3.0.0 的 package.json 中增加一个入口:
"main:h5": "dist/index.esm.js",
让 taro 把 index.esm.js 作为 taro-ui 的入口即可。