I am trying for hours but can not import and use three.js

Steps that I followed:
-Downloaded three.js master from github. Imported to project root as “threejs/”
-Index.html (at root):

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>3D Demo</title>
	<script type="module" src="index.js"></script>
</head>
<body>
</body>
</html>

-index.js (also at root):

import * as THREE from "./threejs/build/three.module.js";

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

const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

const geometry = new THREE.BoxGeometry( 1, 1, 1 );
const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
const cube = new THREE.Mesh( geometry, material );
scene.add( cube );

camera.position.z = 5;

function Update() {
	requestAnimationFrame( Update );

	cube.rotation.x += 0.01;
	cube.rotation.y += 0.01;

	renderer.render( scene, camera );
};

Update();

-Test, and it works. However, I when I try to also import either OrbitControls or GLTFLoader I get the error:

Uncaught TypeError: Error resolving module specifier “three”. Relative module specifiers must start with “./”, “../” or “/”.

coming from either of those two files at the line where they [import {...} from "three"]

How do I fix this without importing from CDN?
(I tried using the cdn version but I had similar trouble there, even after using an import map as suggested).
I have spent many many hours trying to figure this out with no avail. I am extremely thankful to whoever helps.

This is how I went about importing OrbitControls, right below the line where I import three.js:

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

Correct me if I’m mistaken here, but I believe a bundler (such as vite, rollup or webpack) is required when using other modules like what you’re trying to do.

Using a bundler is good practice anyways :smile:

The OP needs to define an import map. Something like:

<script type="importmap">
    {
        "imports": {
            "three": "../build/three.module.js"
        }
    }
</script>

A bundler is not required to use the modules in examples/jsm.

1 Like

same as this: Orbit Controls - Install with cdn - #2 by drcmda

  1. install node
  2. type “npm create vite”, name your project, select “vanilla”
  3. cd into your project
  4. run “npm install three”
  5. run “npm run dev”

run the commands, you are set up under 10 seconds. keep in mind that browser esm is unfinished. building import maps, servers to run it, file watchers that refresh the site on save, something that compresses and builds it so you can publish, etc — no sense in doing this by hand.

1 Like

Couldn’t run npm create vite with an error: sh: 1: create-vite: Permission denied.
Solutions online didn’t help, and now I made the imports work by manually changing the imports in my local files to point to the path of three.module.js relatively.
e.g instead of:

import {
  ...
} from 'three'

I made it

import {
  ...
} from "../../../build/three.module.js"