How to implement ThreeJS please without type="module"

Hi I’m afraid I’m struggling with a basic implementation of ThreeJS. I have it all working great using NPM and it’s all neatly packaged in my main.js file. I load a .glb 3d model and GLTFLoader and OrbitControls are all nicely imported and everything is great. My problem now is that I need to load my 3d model from a database so I don’t need the whole javascript neatly packaged in my JS file. I can do this by importing the correct script like this:

<script type="module">
    import * as THREE from './js/three.module.js';
    import { GLTFLoader } from './examples/jsm/loaders/GLTFLoader.js';
    import { OrbitControls } from './examples/jsm/controls/OrbitControls.js'; 
    // rest of my script goes here

This again works fine but the problem is the CMS I’m using has a problem with type=“module” so is there a different way to implement it without using that bit?

Thanks in advance for any help.

According to your lib folder structure suggested in your code above, it would be something like this,

<script src="./js/three.min.js"></script>
<script src="./examples/js/loaders/GLTFLoader.js"></script>
<script src="./examples/js/controls/OrbitControls.js"></script>
<script>
// rest of your script goes here
</script>

The libs in this version,

  • are being loaded using script tags and not es6 import statements.
  • are in the /examples/js folder and not the /examples/jsm folder
  • the three lib is either three.js or three.min.js and not the three.module.js

Thanks very much for your reply. Unfortunately it didn’t work. I get two warnings and an error in Firefox:

THREE.GLTFLoader: As part of the transition to ES6 Modules, the files in ‘examples/js’ were deprecated in May 2020 (r117) and will be deleted in December 2020 (r124). You can find more information about developing using ES6 Modules in https://threejs.org/docs/#manual/en/introduction/Installation.

THREE.OrbitControls: As part of the transition to ES6 Modules, the files in ‘examples/js’ were deprecated in May 2020 (r117) and will be deleted in December 2020 (r124). You can find more information about developing using ES6 Modules in https://threejs.org/docs/#manual/en/introduction/Installation.

Uncaught ReferenceError: OrbitControls is not defined

You are right about the folder structure.

Paste your code where you declare your ObitControls variable and I will tell you what you did wrong. You left it out of your original code sample.
I guess its in the bit where you say

// rest of my script goes here

And the warnings, well they are warnings and to stop those particular warnings, you can use type="module"

    const scene = new THREE.Scene();
    var container;
    container = document.getElementById( "stage" );

    scene.background = new THREE.Color().setHSL( 0.6, 0, 1 );
    scene.fog = new THREE.Fog( scene.background, 1, 5000 );

    var hemiLight = new THREE.HemisphereLight( 0xffffff, 0x444444, 1.5 );
    hemiLight.position.set( 0, 300, 0 );
    scene.add( hemiLight );

    var dirLight = new THREE.DirectionalLight( 0xffffff );
    dirLight.position.set( 75, 300, -75 );


    scene.add( dirLight );

    var containerWidth = container.offsetWidth;
    console.log(containerWidth);
    var containerHeight = (containerWidth / 3)*2;
    var camera = new THREE.PerspectiveCamera( 75, containerWidth / containerHeight, 0.1, 1000 );


    var axesHelper = new THREE.AxesHelper( 5 );
    scene.add( axesHelper );


    function rotateObject(object, degreeX=0, degreeY=0, degreeZ=0) {
        object.rotateX(THREE.Math.degToRad(degreeX));
        object.rotateY(THREE.Math.degToRad(degreeY));
        object.rotateZ(THREE.Math.degToRad(degreeZ));
    }

    var renderer = new THREE.WebGLRenderer( { alpha: true, antialias: true  } );

    renderer.setSize( containerWidth, containerHeight );

    renderer.setClearColor( 0xffffff, 0);

    renderer.outputEncoding = THREE.sRGBEncoding;

    const controls = new OrbitControls( camera, renderer.domElement );

    camera.position.y = 0.1; //move down slightly
    camera.position.z = 2; //zoom

    controls.update();

    var loader = new GLTFLoader();

    var bench = "";

    loader.load( 'bench.glb', function ( gltf ) {

        bench = gltf.scene;

        scene.add( gltf.scene );

    }, undefined, function ( error ) {

        console.error( error );

    } );

    container.appendChild( renderer.domElement );


    function addObj(obj){
        scene.remove(bench); /* removing the square object here, */

        loader.load( obj+'.glb', function ( gltf ) {

            bench = gltf.scene;

            scene.add( gltf.scene );

        }, undefined, function ( error ) {

            console.error( error );

        } );

    };

    document.querySelectorAll(".control3d").forEach(control3d => {
        control3d.addEventListener("click", (e) => {
            e.preventDefault();
            addObj(control3d.id);
        })
    });

    function myFunction(e) {
        e.preventDefault();
        camera.position.y = 0.1; //move down slightly
        camera.position.z = 2; //zoom
        camera.position.x = 0;


        controls.update();
    }

    document.getElementById("reset").addEventListener("click", myFunction);

    var animate = function () {
        requestAnimationFrame( animate );


        renderer.render( scene, camera );
    };

    animate();

Change that line to

const controls = new THREE.OrbitControls( camera, renderer.domElement );

I am presuming your CMS is able to handle the const

Great that got it. Thank you. I had to also apply the same to:

var loader = new GLTFLoader();

As regards to your question about const, I can only hope that it does… I’ll be checking that shortly.

Thanks for your help.

1 Like

Yes all worked in the CMS thanks very much.

@cannon303 If you want to keep using modules in your project, you could also use a compiler like Babel or a bundler like Webpack that will automatically convert your code to an older js version, compatible with your CMS.

@cannon303 which CMS are you using? Usually, a CMS handles the backend and shouldn’t care about what style of JavaScript you use.

It’s Craft CMS. You can write javascript right in page where you want it to take effect and it will automatically move it to the bottom of the page and only pull it in if it is specifically required. Unfortunately the best it will do is throw your script into a <script>...</script> tag and not add the type=“module” bit.