最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Three.js project: Uncaught TypeError: Failed to resolve module specifier "three". Relative refere

programmeradmin7浏览0评论

I'm attempting to use cdn to import the three library as well as several add ons and N8AO. As stated in the title I'm encountering the listed error:

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

I'm getting the error in Chrome however I have not tried any other browser yet. I'm also using WebStorm as my development environment.
I have node.js version 22.12.0 installed however I am just scripting the entirety of the functionality in the html file rather than creating a separate javascript file for the sake of having everything in one spot.
I presume it's coming from one of the import statements given here. Also including the rest of the project as it may provide other insights:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Three.js Terrain with Grass and N8AO</title>
  <style>
    body { margin: 0; overflow: hidden; }
    canvas { display: block; }
  </style>
</head>
<body>
<script type="module">
  import * as THREE from '/[email protected]/build/three.module.js';
  import { OrbitControls } from '/[email protected]/examples/jsm/controls/OrbitControls.js';
  import { EffectComposer } from '/[email protected]/examples/jsm/postprocessing/EffectComposer.js';
  import { N8AOPass } from "@latest/dist/N8AO.js";

  // Scene, Camera, Renderer
  const scene = new THREE.Scene();
  const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
  camera.position.set(15, 15, 10);

  const renderer = new THREE.WebGLRenderer({ antialias: true });
  renderer.setSize(window.innerWidth, window.innerHeight);
  renderer.shadowMap.enabled = true;
  renderer.shadowMap.type = THREE.PCFSoftShadowMap;
  document.body.appendChild(renderer.domElement);

  // Controls
  const controls = new OrbitControls(camera, renderer.domElement);
  controls.minPolarAngle = Math.PI / 2.5;
  controls.maxPolarAngle = Math.PI / 2.5;

  // Sky and lighting
  scene.background = new THREE.Color(0xaabbff); // Sky color
  scene.add(new THREE.AmbientLight(0x404040)); // Soft ambient light

  const pointLight = new THREE.PointLight(0xffffff, 1);
  pointLight.position.set(10, 10, 10);
  pointLight.castShadow = true;
  scene.add(pointLight);

  // Terrain
  const width = 100;
  const terrainGeometry = new THREE.PlaneGeometry(width, width, 64, 64);
  terrainGeometry.rotateX(-Math.PI / 2);

  // Generate elevation for terrain
  const simplex = new THREE.SimplexNoise();
  for (let i = 0; i < terrainGeometry.attributes.position.count; i++) {
    const x = terrainGeometry.attributes.position.array[i * 3];
    const z = terrainGeometry.attributes.position.array[i * 3 + 2];
    const y = 2 * simplex.noise2D(x / 10, z / 10) + 3 * simplex.noise2D(x / 15, z / 15);
    terrainGeometry.attributes.position.array[i * 3 + 1] = y;
  }
  terrainGeometryputeVertexNormals();

  const terrainMaterial = new THREE.MeshStandardMaterial({ color: 0x228b22 });
  const terrain = new THREE.Mesh(terrainGeometry, terrainMaterial);
  terrain.receiveShadow = true;
  scene.add(terrain);

  // Grass
  const grassGroup = new THREE.Group();
  const bladeGeometry = new THREE.PlaneGeometry(0.12, 1, 1, 4).translate(0, 0.5, 0);
  const grassMaterial = new THREE.MeshStandardMaterial({ color: 0x32cd32, side: THREE.DoubleSide });

  for (let i = 0; i < 50000; i++) {
    const blade = new THREE.Mesh(bladeGeometry, grassMaterial);
    blade.position.set(
            Math.random() * width - width / 2,
            0,
            Math.random() * width - width / 2
    );
    blade.rotation.y = Math.random() * Math.PI * 2;
    blade.scale.y = 0.5 + Math.random() * 0.5;
    grassGroup.add(blade);
  }
  scene.add(grassGroup);

  // Post-Processing with N8AOPass
  const composer = new EffectComposer(renderer);
  const n8aoPass = new N8AOPass(scene, camera, window.innerWidth, window.innerHeight);
  composer.addPass(n8aoPass);

  // Adjust N8AOPass Parameters
  n8aoPass.configuration.aoRadius = 5.0; // Set AO radius
  n8aoPass.configuration.distanceFalloff = 1.0; // Distance attenuation
  n8aoPass.configuration.intensity = 3.0; // AO intensity
  n8aoPass.configuration.color = new THREE.Color(0, 0, 0); // AO color
  n8aoPass.configuration.halfRes = false; // Full resolution for better quality

  // Animation loop
  function animate() {
    requestAnimationFrame(animate);

    // Simulate grass swaying in the wind
    grassGroup.children.forEach((blade) => {
      blade.rotation.x = 0.1 * Math.sin(performance.now() / 1000 + blade.position.x);
    });

    composer.render();
  }
  animate();

  // Handle resizing
  window.addEventListener("resize", () => {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth, window.innerHeight);
    composer.setSize(window.innerWidth, window.innerHeight);
  });
</script>
</body>
</html>

The version of Chrome I am using is 131.0.6778.109
The version of Webstorm I'm using is #WS-242.21829.149

I'm attempting to use cdn to import the three library as well as several add ons and N8AO. As stated in the title I'm encountering the listed error:

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

I'm getting the error in Chrome however I have not tried any other browser yet. I'm also using WebStorm as my development environment.
I have node.js version 22.12.0 installed however I am just scripting the entirety of the functionality in the html file rather than creating a separate javascript file for the sake of having everything in one spot.
I presume it's coming from one of the import statements given here. Also including the rest of the project as it may provide other insights:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Three.js Terrain with Grass and N8AO</title>
  <style>
    body { margin: 0; overflow: hidden; }
    canvas { display: block; }
  </style>
</head>
<body>
<script type="module">
  import * as THREE from 'https://unpkg.com/[email protected]/build/three.module.js';
  import { OrbitControls } from 'https://unpkg.com/[email protected]/examples/jsm/controls/OrbitControls.js';
  import { EffectComposer } from 'https://unpkg.com/[email protected]/examples/jsm/postprocessing/EffectComposer.js';
  import { N8AOPass } from "https://unpkg.com/n8ao@latest/dist/N8AO.js";

  // Scene, Camera, Renderer
  const scene = new THREE.Scene();
  const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
  camera.position.set(15, 15, 10);

  const renderer = new THREE.WebGLRenderer({ antialias: true });
  renderer.setSize(window.innerWidth, window.innerHeight);
  renderer.shadowMap.enabled = true;
  renderer.shadowMap.type = THREE.PCFSoftShadowMap;
  document.body.appendChild(renderer.domElement);

  // Controls
  const controls = new OrbitControls(camera, renderer.domElement);
  controls.minPolarAngle = Math.PI / 2.5;
  controls.maxPolarAngle = Math.PI / 2.5;

  // Sky and lighting
  scene.background = new THREE.Color(0xaabbff); // Sky color
  scene.add(new THREE.AmbientLight(0x404040)); // Soft ambient light

  const pointLight = new THREE.PointLight(0xffffff, 1);
  pointLight.position.set(10, 10, 10);
  pointLight.castShadow = true;
  scene.add(pointLight);

  // Terrain
  const width = 100;
  const terrainGeometry = new THREE.PlaneGeometry(width, width, 64, 64);
  terrainGeometry.rotateX(-Math.PI / 2);

  // Generate elevation for terrain
  const simplex = new THREE.SimplexNoise();
  for (let i = 0; i < terrainGeometry.attributes.position.count; i++) {
    const x = terrainGeometry.attributes.position.array[i * 3];
    const z = terrainGeometry.attributes.position.array[i * 3 + 2];
    const y = 2 * simplex.noise2D(x / 10, z / 10) + 3 * simplex.noise2D(x / 15, z / 15);
    terrainGeometry.attributes.position.array[i * 3 + 1] = y;
  }
  terrainGeometry.computeVertexNormals();

  const terrainMaterial = new THREE.MeshStandardMaterial({ color: 0x228b22 });
  const terrain = new THREE.Mesh(terrainGeometry, terrainMaterial);
  terrain.receiveShadow = true;
  scene.add(terrain);

  // Grass
  const grassGroup = new THREE.Group();
  const bladeGeometry = new THREE.PlaneGeometry(0.12, 1, 1, 4).translate(0, 0.5, 0);
  const grassMaterial = new THREE.MeshStandardMaterial({ color: 0x32cd32, side: THREE.DoubleSide });

  for (let i = 0; i < 50000; i++) {
    const blade = new THREE.Mesh(bladeGeometry, grassMaterial);
    blade.position.set(
            Math.random() * width - width / 2,
            0,
            Math.random() * width - width / 2
    );
    blade.rotation.y = Math.random() * Math.PI * 2;
    blade.scale.y = 0.5 + Math.random() * 0.5;
    grassGroup.add(blade);
  }
  scene.add(grassGroup);

  // Post-Processing with N8AOPass
  const composer = new EffectComposer(renderer);
  const n8aoPass = new N8AOPass(scene, camera, window.innerWidth, window.innerHeight);
  composer.addPass(n8aoPass);

  // Adjust N8AOPass Parameters
  n8aoPass.configuration.aoRadius = 5.0; // Set AO radius
  n8aoPass.configuration.distanceFalloff = 1.0; // Distance attenuation
  n8aoPass.configuration.intensity = 3.0; // AO intensity
  n8aoPass.configuration.color = new THREE.Color(0, 0, 0); // AO color
  n8aoPass.configuration.halfRes = false; // Full resolution for better quality

  // Animation loop
  function animate() {
    requestAnimationFrame(animate);

    // Simulate grass swaying in the wind
    grassGroup.children.forEach((blade) => {
      blade.rotation.x = 0.1 * Math.sin(performance.now() / 1000 + blade.position.x);
    });

    composer.render();
  }
  animate();

  // Handle resizing
  window.addEventListener("resize", () => {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth, window.innerHeight);
    composer.setSize(window.innerWidth, window.innerHeight);
  });
</script>
</body>
</html>

The version of Chrome I am using is 131.0.6778.109
The version of Webstorm I'm using is #WS-242.21829.149

Share Improve this question edited Dec 9, 2024 at 15:53 Rabbid76 210k29 gold badges156 silver badges196 bronze badges asked Dec 9, 2024 at 6:02 ZodiacZodiac 412 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 2

if you open e.g. https://unpkg.com/n8ao@latest/dist/N8AO.js you may notice:

import {Color as $5Whe3$Color, ...a lot of stuff here} from "three";
import {Pass as $5Whe3$Pass} from "three/examples/jsm/postprocessing/Pass.js";
import {Pass as $5Whe3$Pass1} from "postprocessing";

That is the root of the error you see. A browser can import a module using a module specifier that is either an absolute URL, or a relative URL that is resolved using the base URL. To solve it you may use importmap:

<script type="importmap">

In your case that importmap should work:

<script type="importmap">
        {
            "imports": {
                "three": "https://unpkg.com/[email protected]/build/three.module.js",
                "three/examples/": "https://unpkg.com/[email protected]/examples/",
                "postprocessing"   : "https://unpkg.com/[email protected]/build/index.js"            
            }
        }
</script>
<script type="module">
  // your code here
<script>

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论