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);
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With