Attempted import error: 'OrbitControls' is not exported from 'three' (imported as 'THREE')

Hi, I am new to THREE.js and I am trying to make an 3D object rotate using ReactJS… but I can’t import OrbitControls I always get this error: Attempted import error: ‘OrbitControls’ is not exported from ‘three’ (imported as ‘THREE’).

when I try to import it directly like that: import { OrbitControls } from “three/examples/jsm/controls/OrbitControls”;

I get that: ReferenceError: THREE is not defined

I’ve also tried installing few NPM Packages but I end up with : Module not found: Can’t resolve ‘three-orbit-controls’…

THE CODE:

import React, { Component } from "react";
import "./style.css";
import * as THREE from "three";
import texture from "./images/earthmap1k.jpg";

class Earth extends Component {
 componentDidMount() {
  var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  1000
   );
    camera.position.z = 1;
    camera.position.set(250, 200, 250);
    camera.lookAt(0, 0, 0);
   var controls = new OrbitControls(this.camera, this.mount);

var renderer = new THREE.WebGLRenderer({ antialias: true });
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
renderer.setClearColor("#00000");
renderer.setSize(window.innerWidth, window.innerHeight);

var light = new THREE.DirectionalLight(0xcccccc, 1);
light.position.set(5, 5, 5);
scene.add(light);
light.castShadow = true;
light.shadowCameraNear = 0.01;
light.shadowCameraFar = 15;
light.shadowCameraFov = 45;

light.shadowCameraLeft = -1;
light.shadowCameraRight = 1;
light.shadowCameraTop = 1;
light.shadowCameraBottom = -1;

light.shadowBias = 0.001;
light.shadowDarkness = 0.2;

light.shadowMapWidth = 1024;
light.shadowMapHeight = 1024;
this.mount.appendChild(renderer.domElement);
// window.addEventListener("resize", () => {
//   renderer.setSize(window.innerWidth, window.innerHeight);
//   camera.aspect = window.innerWidth / window.innerHeight;
//   camera.updateProjectionMatrix();
// });

var render = function () {
  requestAnimationFrame(render);
  renderer.render(scene, camera);
};

var geometry = new THREE.SphereGeometry(0.5, 32, 32);
var material = new THREE.MeshPhongMaterial();
material.map = THREE.ImageUtils.loadTexture(texture);
// material.bumpMap = THREE.ImageUtils.loadTexture("images/earthbump1k.jpg");
// material.bumpScale = 0.05;
// material.specularMap = THREE.ImageUtils.loadTexture(
//   "images/earthspec1k.jpg"
// );
// material.specular = new THREE.Color("grey");
var earthMesh = new THREE.Mesh(geometry, material);

scene.add(earthMesh);

render();
 }
   render() {
return <div ref={(ref) => (this.mount = ref)} />;
 }
}
 export default Earth;

You need to make 2 import statements, and then treat them separately. Everything that’s part of the core Three.js library will be under THREE.XXX and the orbit controls will be standalone, not inside of THREE

import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

// ...

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera();
var controls = new OrbitControls();

Notice that OrbitControls does not need THREE. in front of it, because you imported it independently.

1 Like

What version of Three.js are you using in your project?

If you look at the latest version of examples/jsm/controls/OrbitControls.js you can see that the class begins with the line

var OrbitControls = function ( object, domElement ) {

But for some reason, your error in React says it starts with

var THREE.OrbitControls = function ( object, domElement ) {

I’m pretty certain that updating to the latest version of Three.js would solve this issue.

Thank you so much :slight_smile: you have saved me from the inevitable feeling of being stuck…
The solution is to enter node_modules/three/examples/jsm/controls/OrbitControls.js then copy/paste the latest update from here : examples/jsm/controls/OrbitControls.js then save the changes…:heart:

OMG I am so happy :heart::heart: THANK YOU SO MUCH

That’s one way to solve it, true… but manually editing files inside your node_modules folder means that it will break if someone else tries to install your project because their version of node_modules will not have the edits you added.

You might want to copy/paste the OrbitControls.js file into your own folder, and point to that new file.

Instead of:

import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

point to your own copy:

import { OrbitControls } from "./path/to/my_folder/OrbitControls";
1 Like

related
Module Import / Usage (page 18)
Module Import / Usage (page 22)

:slightly_smiling_face: