javascriptthree.js

Three.js breaks when trying to import OrbitControls.js


First I want to say that I'm very new to javascript and working with libraries. I'm trying to get some basic three.js code to work but it's not working and I'm not sure why. I have set up a basic scene using the Threejs.org documentation and I'm trying to get some basic orbit controls set up. Everything works fine until I try to import the orbit controls into my main script file. I then get an error:

Uncaught TypeError: Failed to resolve module specifier "three". Relative references must start with either "/", "./", or "../".

I haven't tried much to solve my problem because I'm not even sure where to start. I've checked my spelling and made sure I had the correct relative path for my imports.

Here is the code that works:

import * as THREE from '/node_modules/three/build/three.module.js';

// import { OrbitControls } from '/node_modules/three/examples/jsm/controls/OrbitControls.js';

// Construct basic scene elements
const camera = new THREE.PerspectiveCamera(
    75,
    window.innerWidth / window.innerHeight,
    1,
    1000
);
const renderer = new THREE.WebGLRenderer();
const scene = new THREE.Scene();
// const controls = new OrbitControls(camera, renderer.domElement);

// Set parameters for scene elements
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

When I uncomment the second import for the orbit controls it breaks and gives me the error above. What is causing the error and how do I fix it?

Thanks in advance.


Solution

  • Welcome to Stack Overflow. You question seems to be missing some information, so I'm going to make some assumptions based on what you have provided. If any of my assumptions are incorrect, please update your question to provide further details.

    My primary assumption is that you are using a <script> tag in your HTML to reference your main file, and that you are not using any JavaScript bundling tools like Mugen87 mentioned. If this is the case, then what you have is fine, BUT, OrbitControls will not work unless you modify it.

    If you dig into the OrbitControls.js file, you'll see (current as of r.130.1):

    import {
        EventDispatcher,
        MOUSE,
        Quaternion,
        Spherical,
        TOUCH,
        Vector2,
        Vector3
    } from 'three';
    

    The from reference makes the assumption that you are using the module from within an npm context, not a browser. Browsers don't know anything about npm packages, and they can't resolve three to its node_modules path, resulting in the error you saw. To make this work, you will need to modify the reference to point to the correct module path.

    I personally don't like modifying the files inside node_modules, so I recommend the following:

    1. Make a new folder called vendor_mods/three/examples/jsm/controls and copy OrbitControls.js into it.
    2. Change the from reference in the copied file to point to /node_modules/three/build/three.module.js
    3. Change the reference in your main file to point to your modified OrbitControls.js.

    Now, the browser can reference all the pieces correctly, and everyone should be happy.