Error when trying to import GLTFLoader

I looked everywhere before asking here - searching Google, StackOverflow, discourse.threejs.org, Youtube - I even tried asking YouChat.

But as they couldn’t resolve my issue, I’m asking you here.

HTML

<!DOCTYPE html>
<html>
	<head>
		<title>Tidally locked world game</title>
		<meta charset="UTF-8">
		<link rel="stylesheet" href="style.css">
		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
		
		<!-- CrazyGames SDK - only for deployment on CrazyGames -->
		<script src="https://sdk.crazygames.com/crazygames-sdk-v1.js"></script>
	</head>
	<body>
		<canvas id="game-canvas"></canvas>
		
		<!-- Scripts -->
		<script type="importmap">
			{
				'imports' :{
					'three': './three/build/three.module.js'
				}
			}
		</script>
		<script src="script.js" type="module"></script>
	</body>
</html>

JS

"use strict"

// Imports
import * as THREE from './three/build/three.module.js';
import {GLTFLoader} from './three/examples/jsm/loaders/GLTFLoader.js';

// Basic functions

function byId(id) {
	return(document.getElementById(id))
};

// Setup

// vars
const fps = 60;

// three.js
const scene = new THREE.Scene();

// Add objects
const geometry = new THREE.BoxGeometry( 1, 1, 1 );
const material = new THREE.MeshStandardMaterial();
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);

const camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.05, 1000000000);
scene.add(camera);

const sun = new THREE.PointLight(0xf78f73, 1, 0, 0);
const ambientLight = new THREE.AmbientLight(0x101010);
scene.add(sun);
scene.add(ambientLight);

const planet = new THREE.Mesh(new THREE.SphereGeometry(10000000, 200, 100), new THREE.MeshStandardMaterial({color: 0xffc65c}));
scene.add(planet);

// Setup objects
sun.position.set(0, 5000000000, 0);

camera.position.set(0, 0, 20000000);

// Setup renderer
const renderer = new THREE.WebGLRenderer({canvas: byId('game-canvas')});


// Logic

function logic() {
	cube.rotation.x += 0.01;
	cube.rotation.y += 0.01;
};

let logicInterval = setInterval(logic, 1000 / fps);


// Render

function render() {
	requestAnimationFrame(render);
	
	renderer.setSize(byId('game-canvas').offsetWidth, byId('game-canvas').offsetHeight);
	renderer.render(scene, camera);
};

render();

When I try to run this on my remotely hosted website (https://jackgreenearth.org/projects/alien-game/index), it comes up with the error

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

I’ve seen videos and guides, and even examples where it seemed others got this to work without modifying the GLTFLoader.js file, so it must be some really simple error I’ve made, but I can’t see it in my own code, and numerous searches have yielded nothing, so I turn to you to help.

Will you be the reason my code runs today?

If you can help me, please reply, thank you!

Oops, almost forgot to mention: I’m running this on Firefox 104.0.2 (64-bit) on Manjaro Linux.

Edit: Please help me, I’m at my wit’s end.

you need to include jsm in you import maps…
try like so

		<script type="importmap">
			{
				'imports' :{
					'three': './three/build/three.module.js',
                    'three/addons/': './three/examples/jsm/'
				}
			}
		</script>

and then in your script.js

import {GLTFLoader} from 'three/addons/loaders/GLTFLoader.js';

I really appreciate you trying to help - I changed my code the way you said, and got this error when I tried to run it:

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

that’s odd did you also update your importmap? try putting the import map before any other script tags and remember to include es-module-shims like so

<script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script>

<script type="importmap">
	{
	"imports": {
	    'three': './three/build/three.module.js',
        'three/addons/': './three/examples/jsm/'
		}
	}
</script>

also i’m pretty sure you can negate “use strict” when using es6 modules…

I did update the importmap:

<script type="importmap">	
	{
		'imports' :{
			'three': './three/build/three.module.js',
			'three/addons/': './three/examples/jsm/'
		}
	}
</script>

and when I tried putting it in the header like you suggested nothing changed :(. Same error, it still didn’t work. Also, I’m not quite sure what you mean by ‘negating’ use strict.

did you add this line? this is equivalent to “polyfill” for import maps needed for cross browser support of import maps

you can delete the line

Thanks for clearing that up about strict mode, I didn’t actually have that ‘shims’ line,
so I added it before the importmap.

Of course, that just gave me more errors:

Uncaught SyntaxError: JSON.parse: expected property name or '}' at line 3 column 5 of the JSON data
    importMapPromise https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js:741
    promise callback*processImportMap https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js:740
    processImportMaps https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js:674
    <anonymous> https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js:715
    EventListener.handleEvent* https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js:714
    <anonymous> https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js:789

I also got this long error:

Uncaught SyntaxError: JSON.parse: expected property name or '}' at line 3 column 5 of the JSON data
    importMapPromise https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js:741
    promise callback*processImportMap https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js:740
    processImportMaps https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js:674
    <anonymous> https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js:715
    EventListener.handleEvent* https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js:714
    <anonymous> https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js:789

Hey! I changed something, and now it’s rendering, although I still get an error.

Updated HTML:

<!DOCTYPE html>
<html>
	<head>
		<title>Tidally locked world game</title>
		<meta charset="UTF-8">
		<link rel="stylesheet" href="style.css">
		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
		
		<!-- CrazyGames SDK - only for deployment on CrazyGames -->
		<script src="https://sdk.crazygames.com/crazygames-sdk-v1.js"></script>
		
		<!-- Import maps polyfill -->
		<!-- Remove this when import maps will be widely supported -->
		<script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script>

		<script type="importmap">
			{
				"imports": {
					"three": "./three/build/three.module.js",
					"three/addons/": "./three/examples/jsm/"
				}
			}
		</script>
	</head>
	<body>
		<canvas id="game-canvas"></canvas>
		
		<!-- Scripts -->
		
		<script src="script.js" type="module"></script>
	</body>
</html>

JS

// Imports
import * as THREE from 'three';
import {GLTFLoader} from 'three/addons/loaders/GLTFLoader.js';

// Basic functions

function byId(id) {
	return(document.getElementById(id))
};

// Setup

// vars
const fps = 60;

// three.js
const scene = new THREE.Scene();

// Add objects
const geometry = new THREE.BoxGeometry( 1, 1, 1 );
const material = new THREE.MeshStandardMaterial();
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);

const camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.05, 1000000000);
scene.add(camera);

const sun = new THREE.PointLight(0xf78f73, 1, 0, 0);
const ambientLight = new THREE.AmbientLight(0x101010);
scene.add(sun);
scene.add(ambientLight);

const planet = new THREE.Mesh(new THREE.SphereGeometry(10000000, 200, 100), new THREE.MeshStandardMaterial({color: 0xffc65c}));
scene.add(planet);

// Setup objects
sun.position.set(0, 5000000000, 0);

camera.position.set(0, 0, 20000000);

// Setup renderer
const renderer = new THREE.WebGLRenderer({canvas: byId('game-canvas')});


// Logic

function logic() {
	cube.rotation.x += 0.01;
	cube.rotation.y += 0.01;
};

let logicInterval = setInterval(logic, 1000 / fps);


// Render

function render() {
	requestAnimationFrame(render);
	
	renderer.setSize(byId('game-canvas').offsetWidth, byId('game-canvas').offsetHeight);
	renderer.render(scene, camera);
};

render();

Error:

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

great, that’s good, if it’s rendering but you’re seeng the error in firefox i’m quite sure older versions of firefox still show that error for some reason, i think it may be to do with shims being an async script and takes a moment to resolve the actual import map

I am glad that is resolved! Have a good night, if it is night where you are.

:beers: cheers you too, as a heads up, if you’re going to be loading gltf models you may want to use THREE.LoadingManager() and run your

in a containing function that runs once loading is complete