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

i have this simple js sample which i test via visual studio code with live preview server build in: i don't use node.js in this sample all js files under js dir :

C:\Dev\my\javascript\ThreeJS\tests\js>ls -1
GLTFLoader.js
OrbitControls.js
main.js
three.js
three.min.js
three.module.js

HTML:

but i keep getting this general error :

   Uncaught TypeError: Failed to resolve module specifier "three". Relative references must start with either "/", "./", or "../".
<html>
    <head>
        
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta charset="UTF-8" />
        <title>My first three.js app</title>
        <link href="main.css" rel="stylesheet" type="text/css">
        <script type="module" src="js/main.js"></script>
    </head>
    <body>
        <div id="scene-container">
            <canvas></canvas>
        </div>
    </body>
</html>

in js/main.js

import {
  BoxBufferGeometry,
  Color,
  Mesh,
  MeshBasicMaterial,
  PerspectiveCamera,
  Scene,
  WebGLRenderer,
} from 'three';

// Get a reference to the container element that will hold our scene
const container = document.querySelector('#scene-container');

// create a Scene
const scene = new Scene();

// Set the background color
scene.background = new Color('skyblue');

// Create a camera
const fov = 35; // AKA Field of View
const aspect = container.clientWidth / container.clientHeight;
const near = 0.1; // the near clipping plane
const far = 100; // the far clipping plane

const camera = new PerspectiveCamera(fov, aspect, near, far);

// every object is initially created at ( 0, 0, 0 )
// move the camera back so we can view the scene
camera.position.set(0, 0, 10);

// create a geometry
const geometry = new BoxBufferGeometry(2, 2, 2);

// create a default (white) Basic material
const material = new MeshBasicMaterial();

// create a Mesh containing the geometry and material
const cube = new Mesh(geometry, material);

// add the mesh to the scene
scene.add(cube);

// create the renderer
const renderer = new WebGLRenderer();

// next, set the renderer to the same size as our container element
renderer.setSize(container.clientWidth, container.clientHeight);

// finally, set the pixel ratio so that our scene will look good on HiDPI displays
renderer.setPixelRatio(window.devicePixelRatio);

// add the automatically created <canvas> element to the page
container.append(renderer.domElement);

// render, or 'create a still image', of the scene
renderer.render(scene, camera);


Solution 1:[1]

write namespace THREE and import like this.....

  import * as THREE from 'fileUrl';

for more info go to this link https://discoverthreejs.com/book/introduction/get-threejs/

Solution 2:[2]

The following is my code when using cdn without webpack/node.js.

#index.html

<head>
    <script type="importmap">
        {
            "imports": {
                "three": "https://unpkg.com/[email protected]/build/three.module.js",
                "OrbitControls": "https://unpkg.com/[email protected]/examples/jsm/controls/OrbitControls.js"
            }
        }
    </script>
</head>
<body>
  <script type="module" src="js/test.js"></script>
</body>

#test.js

import * as THREE from 'three';
import { OrbitControls } from 'OrbitControls';

scene = new THREE.Scene();
renderer = new THREE.WebGLRenderer();
controls = new OrbitControls(camera, renderer.domElement);

ref: https://jspm.org/import-map-cdn

This is because unlike other web resources, the JS modules specification for HTML reserved the space of these non-relative references (called "bare specifiers") exactly to allow custom package imports via import maps.

Solution 3:[3]

I understand your question as follows: You want to include the distributed three.js file into your HTML file without bundling your code (using e.g. webpack). If that's the case, you should not use import in your own code, but rather globally import the dependency (three) into your HTML file. This will expose the THREE object into the global namespace. Then, in your JavaScript file, you automatically have access to the global variables. You can directly access the module (without referencing to it).

Here is an example (taken and adapted from the official documentation):

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>My first three.js app</title>
        <style>
            body { margin: 0; }
        </style>
    </head>
    <body>
    <script src="js/three.js"></script>
    <script src="js/my-script.js"></script>
</body>

my-script.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 );

To reuse your existing code, you can use the spread operator and break down the global variable into your now imported ones:

const {
  BoxBufferGeometry,
  Color,
  Mesh,
  MeshBasicMaterial,
  PerspectiveCamera,
  Scene,
  WebGLRenderer,
} = window.THREE;

Solution 4:[4]

if you are using 'three' package from npm thenyou need to install that pakage in terminal and import like this

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

or
import {
  BoxBufferGeometry,
  Color,
  Mesh,
  MeshBasicMaterial,
  PerspectiveCamera,
  Scene,
  WebGLRenderer,
} from 'three';

Solution 5:[5]

Also since 26th of January this year three.js released r137 update and since r137 using ES6 modules like GLTFLoader in the browser requires an import map.

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

The three.js import statement in your scripts.js looks like so then:

import * as THREE from 'three'

https://github.com/Kramzin/threejs-task - Here you can see updated and previous code, after these changes everything is working.

Solution 6:[6]

My solution is to make a correct directory link to file three.module.js according to the solution from ThreeJS discourse for Mozilla Firefox case when importmap of script is not working by changing from:

import * as THREE from 'three';

to be the correct directory to file three.module.js according to this example depended upon the place of the html file or javascript file that cause the trouble :

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

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Sanoodia
Solution 2 ouflak
Solution 3
Solution 4
Solution 5 Rim
Solution 6