During my work on an Angular 9 project, I encountered a situation where webpack
was being used to manage dependencies.
The specific imports in question were:
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);
...
The error message displayed in the console matched the one you are experiencing:
core:a-node:error Failure loading node:
Error: `Entity.setObject3D` was called with an object that was not an instance of THREE.Object3D.
A closer look at the transpiled code revealed that the import for THREE was treated as a Module object:
/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! three */ "./node_modules/three/build/three.module.js");
This meant that
three__WEBPACK_IMPORTED_MODULE_2__
was used as the reference for creating the
Mesh
, rather than the global
THREE
object. Meanwhile, the imported
AFRAME
did have a reference to the global
THREE
.
three__WEBPACK_IMPORTED_MODULE_2__ === THREE
// false
aframe__WEBPACK_IMPORTED_MODULE_1__.THREE === THREE
// true
In TypeScript, AFRAME.THREE
can be recognized as the THREE
type, eliminating the need for importing THREE
separately if using AFRAME.THREE
.
Here is an example illustrating the usage of 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);
}
});