我在一个 Angular 9 项目中工作,该项目使用 webpack 来处理依赖关系。
有以下这些导入
import { Component, OnInit } from '@angular/core';
import * as AFRAME from 'aframe';
import * as THREE from 'three';
...
AFRAME.registerComponent('box', {
...
// Create mesh.
this.mesh = new THREE.Mesh(this.geometry, this.material);
// Set mesh on entity.
el.setObject3D('mesh', this.mesh);
...
控制台显示与您的错误相同的错误:
core:a-node:error Failure loading node:
Error: `Entity.setObject3D` was called with an object that was not an instance of THREE.Object3D.
查看转译后的代码,我们看到 THREE 的导入是一个 Module 对象
/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! three */ "./node_modules/three/build/three.module.js");
哪个代码使用three__WEBPACK_IMPORTED_MODULE_2__作为引用来创建Mesh,它不是全局的THREE,而是THREE的一个Module(因为threejs将它作为一个模块提供了build/three.module.js)。
three__WEBPACK_IMPORTED_MODULE_2__ === THREE
// false
three__WEBPACK_IMPORTED_MODULE_2__ + ''
// [object Module]
THREE + ''
// [object Object]
然而,导入的AFRAME 具有对全局THREE 的引用,它在内部将其用于检查实例。请注意,AFRAME 不提供自己作为模块,因此 webpack 解析为全局 AFRAME。
three__WEBPACK_IMPORTED_MODULE_2__ === THREE
// false
aframe__WEBPACK_IMPORTED_MODULE_1__.THREE === THREE
// true
aframe__WEBPACK_IMPORTED_MODULE_1__ === AFRAME
// true
请注意,typescript 能够将 AFRAME.THREE 识别为 THREE 类型,因此具有 THREE 类型的所有优点。
因此,如果您使用的是AFRAME.THREE,则不需要import * as THREE from 'three';。
这是我registerComponent的一个例子
AFRAME.registerComponent('box', {
schema: {
width: {type: 'number', default: 1},
height: {type: 'number', default: 1},
depth: {type: 'number', default: 1},
color: {type: 'color', default: '#AAA'}
},
init() {
const data = this.data;
const el = this.el;
// Extract THREE
const {THREE} = AFRAME;
// Create geometry.
this.geometry = new THREE.BoxBufferGeometry(data.width, data.height, data.depth);
// Create material.
this.material = new THREE.MeshStandardMaterial({color: data.color});
// Create mesh.
this.mesh = new THREE.Mesh(this.geometry, this.material);
// Set mesh on entity.
el.setObject3D('mesh', this.mesh);
}
});