aframevr / aframe

:a: Web framework for building virtual reality experiences.
https://aframe.io/
MIT License
16.69k stars 3.98k forks source link

importing Aframe breaks build #4038

Open wjessup opened 5 years ago

wjessup commented 5 years ago

using the latest dist at https://github.com/aframevr/aframe/tree/master/dist

whenever I try to use es6 modules to import aframe:

import './aframe.min.js'

I get this error:

aframe.min.js:19685 Uncaught TypeError: systems[name] is not a constructor at HTMLElement.value (aframe.min.js:19685) at HTMLElement.value (aframe.min.js:19670) at HTMLElement.value (aframe.min.js:19603) at HTMLElement.wrappedMethod (aframe.min.js:18416) at module.exports.registerElement (aframe.min.js:18325) at Object.104.../../lib/three (aframe.min.js:19538) at o (aframe.min.js:1) at aframe.min.js:1 at Object.147.../package (aframe.min.js:22136) at o (aframe.min.js:1)

wjessup commented 5 years ago

simple jsfiddle w/ the type="module" error. https://jsfiddle.net/wdzsbgvL/

bknill commented 5 years ago

This is working in the fiddle - did you find a solution? I'm having the same problem.

dakotaJang commented 5 years ago

Was ES6 module working before? Seems fine in Chrome but when I switch to Firefox, Edge, or Safari, I get not a constructor error. It would be nice if I can bundle my code in one module file that imports the A-frame and my src code.

subelsky commented 5 years ago

In case this is helpful: I got this error when using the defer attribute on a <script> tag including Aframe. Went away when I took it off. The same issue could occur if using the async attribute...

mattrossman commented 4 years ago

Scripts that have type="module" are automatically assigned the defer property, so they will essentially run at the end of <body>. However, A-Frame requires that the script is included before the body/scene.

I'm not sure why this is the case, as according to this, "the script that registers [custom components] has to be loaded after the DOM is parsed".

Related: #4242.

Type1J commented 2 years ago

The systems var exported has not yet been populated with system constructors. All A-Frame component currently have to be kept out of the DOM until it is populated because the hooks for the web component attaching to the DOM attempts to instantiate systems, if they aren't instantiated. Basically, this is happening because of the order that the bundler is executing global statements. Maybe everything should be in an init() function that's called at global (module) scope. Having the components registered in a function instead of at global scope themselves would allow the control of order; i.e. to init the exported systems object of constructors first, then register the components afterward.

Type1J commented 2 years ago

In other words:

This line https://github.com/aframevr/aframe/blob/master/src/index.js#L81 needs to be executed before this line https://github.com/aframevr/aframe/blob/master/src/index.js#L64 .

If it isn't, then uninitialized things are used when A-Frame components already exist in the DOM.

Type1J commented 2 years ago

Testing my theory, I got core:a-node:error Failure loading node: TypeError: system.setActiveCamera is not a function, so maybe a few more things need to be moved around.

Type1J commented 2 years ago

It seems that there's warnings all over the codebase that say that everything needs to be loaded before the DOM. However, with JS modules, that's not going to happen with a static html file. It seems that the idea of everything needing to be initialized before the DOM needs to be rethought.

Type1J commented 2 years ago

(A script tag with type="module" implies defer, as @mattrossman pointed out above.)

diarmidmackenzie commented 1 year ago

A stack overflow thread that looks related. https://stackoverflow.com/questions/67013254/uncaught-typeerror-systemse-is-not-a-constructor-when-loading-a-frame-dynamic

Turns out i had a leftover aframe tag in the body that i had not removed yet, that somehow was causing the problem, once removed it worked fine.

Type1J commented 1 year ago

Yes, that's the same issue. If anything is in the DOM when A-Frame is loaded, then problems happen.