javascriptthree.js

THREE is not defined (latest versions)


I'm trying to get three.js working via CDN with this in my HTML as explained on their installation page

<script type="importmap">
{
  "imports": {
    "three": "https://cdn.jsdelivr.net/npm/three@0.181.2/build/three.module.js"
  }
}
</script>

<script type="module">
  import * as THREE from 'three';
</script>

<script>
// Try to use it - get an error here
const canvas = document.querySelector('#canvas');
const renderer = new THREE.WebGLRenderer({antialias: true, canvas});
</script>

I get "Uncaught ReferenceError: THREE is not defined" in the console when I do it.

There's no other messages and no errors under the "network" tab in the inspector.

What am I doing wrong?


Solution

  • The code imports THREE inside a module:

    <script type="module">  
         import * as THREE from 'three'  
    </script
    

    While this binds the THREE identifier inside the module to the downloaded and imported namespace object for three, variable names and bound identifiers inside a module are not global and can't be accessed from outside the module. This is why the Uncaught ReferenceError: THREE is not defined" occurs when trying to access it as a global. There is also the point that global code should never try to use THREE before the module has loaded.

    Two solutions you could try:

    1. Insert window.THREE = THREE; as the last line of the existing module and defer execution of the global script until after the module has loaded. Even if this works I'm not sure I would recommend it.
    2. Put the program logic code in the module importing THREE. This is the method shown in the three installation document linked in the post. and avoids trying to detect when the script has been loaded.