Errors : Cannot use import statement outside a module THREE.OrbitControl

Viewed 7500

Im starting with three.js. After trying to implement orbit controls i have some errors. It looks simple but i cannot find a good solution for my errors. When im trying to implement controls like :

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

im getting these errors

Cannot use import statement outside a module and THREE.OrbitControls is not a constructor

I added both threejs and orbitcontrols just before starting a new script. What am I doing wrong here?


        <script src="scripts/three.js"></script>   
        <script src="scripts/OrbitControls.js"></script>

        <script type="text/javascript">
                var scene = new THREE.Scene();

                var camera = new
                THREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight, 0.1, 1000);

                var renderer = new THREE.WebGLRenderer();
                renderer.setSize(window.innerWidth, window.innerHeight);
                renderer.setClearColor(0x888888,1)
                document.body.appendChild(renderer.domElement);

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






4 Answers

Online Resource, Threejs Host, Sample Code


           <script type="module">
            import * as THREE from 'https://three.ipozal.com/threejs/resources/threejs/r110/build/three.module.js';
            import { OrbitControls } from 'https://three.ipozal.com/threejs/resources/threejs/r110/examples/jsm/controls/OrbitControls.js';
            import { OBJLoader2 } from 'https://three.ipozal.com/threejs/resources/threejs/r110/examples/jsm/loaders/OBJLoader2.js';

            function main() {
.....
</script>

Jest solution

The examples that ship in the npm module have not been built and would need to be transformed.

Because I'm not testing these files themselves I just stub them out:

//jest.config.js
  moduleNameMapper: {
    'three/examples/jsm/': '<rootDir/config/jest/mockUndefined.js'
  }

//config/jest/mockUndefined.js
module.exports = undefined

If you really need to include them in tests, a ts-jest solution would look like this:

//jest.config.js
{
  //slow preset - does many extra transforms
  preset: 'ts-jest/presets/js-with-ts-esm',
  transformIgnorePatterns: ['/node_modules/(?!(three/examples/jsm)/)'],

Be warned, the second solution is much slower as now jest has to transform many extra files.

It seems your version of OrbitControls.js is a ES6 module. That means you have to import the controls like so:

<script type="module">

    import * as THREE from 'scripts/three.module.js';
    import { OrbitControls } from 'scripts/OrbitControls.js';

     var scene = new THREE.Scene();

     var camera = new THREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight, 0.1, 1000);

    var renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.setClearColor(0x888888,1)
    document.body.appendChild(renderer.domElement);

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

Notice that the above code uses the three.module.js build file which you can find in the build directory of the official git repository. If you are not familiar with ES6 modules, I suggest you study an existing resource about this topic. E.g. https://exploringjs.com/es6/ch_modules.html

three.js R109

What worked for me was including type="module" as @kaveh-eyni mentioned but then npm installing the "deprecated" modules directly into my project.

  • npm install --save three-orbitcontrols
  • npm i --save three-gltf-loader

and then

<script type="module">
import * as THREE from 'three/build/three.module'
import OrbitControls from 'three-orbitcontrols'
import GLTFLoader from 'three-gltf-loader
Related