如何让Babel适配新版Three.js,解决iOS WebView类继承报错问题
Three.js 升级ES6类版本iOS WebView报错问题解决
问题复现
升级Three.js到官方推出的新版ES6类版本后,继承Object3D实现自定义类的代码仅在iOS WebView环境下运行异常。
自定义类代码如下:
import { Object3D, } from "three"; type Props = { myProp:string }; export default class MyBox extends Object3D { constructor(props: Props = {}) { super(); console.log("HERE"); this.init(props); console.log("Done"); } init(props){ // Do stuff }
代码转译后对应片段为:
function e() { var e, o = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {}; return e = n.call(this) || this, console.log("HERE"), e.init(o), console.log("DOne"), e
iOS WebView抛出错误信息:TypeError: Cannot call a class constructor without |new|
初步排查
最初判断错误原因为Three.js的Object3D是原生ES6类,无法被转译后的ES5构造函数以普通函数形式调用,尝试以下操作均无效果:
- 调整
@babel/preset-env的targets配置 - 升级Babel及Three.js相关依赖包
- 校验Three.js转译逻辑,确认项目其余代码转译正常,排除第三方依赖未转译问题
项目原Babel配置如下:
{ "presets": ["@babel/preset-flow", ["@babel/preset-env", { "targets": ">1%" }], "@babel/react"], "plugins": [ "@babel/transform-runtime", "@babel/plugin-syntax-flow", "@babel/plugin-transform-flow-strip-types", "@babel/plugin-proposal-class-properties"] }
实际根因
最终排查确认,问题与Babel本身转译逻辑无关,是Meteor构建系统错误识别当前运行环境是否为legacy场景,导致构建输出的转译产物逻辑异常。
解决方案
可根据项目兼容需求选择对应方案:
- 若不需要兼容极低版本老旧设备,可设置环境变量
METEOR_DISABLE_LEGACY_BUILD=1,强制Meteor仅输出现代浏览器兼容的构建产物,避免不必要的ES5转译导致新旧类逻辑冲突 - 若需要保留legacy兼容能力,可在
package.json中明确配置browserslist规则,对齐Meteor与Babel的兼容目标,避免转译逻辑不一致 - 也可调整Babel配置,显式关闭类转译的loose模式,保证转译后的类继承逻辑符合ES6规范,可正常继承原生ES6类,参考配置如下:
{ "presets": ["@babel/preset-flow", ["@babel/preset-env", { "targets": ">1%", "include": ["@babel/plugin-transform-classes"] }], "@babel/react"], "plugins": [ ["@babel/plugin-transform-classes", { "loose": false }], "@babel/transform-runtime", "@babel/plugin-syntax-flow", "@babel/plugin-transform-flow-strip-types", "@babel/plugin-proposal-class-properties" ] }
内容的提问来源于stack exchange,提问作者schlaegerz
相关产品推荐
相关产品推荐

