使用Three.js+TypeScript搭建网页时资源加载失败求助
Three.js + TypeScript 本地部署资源加载问题解决方案
报错信息
- GET http://localhost:8081/src/client/main.js net::ERR_ABORTED 404 (Not Found)
- :8081/#:1 拒绝执行脚本,MIME类型('text/html')不符合要求
- localhost/:33 GET http://localhost:8081/node_modules/three/examples/jsm/loaders/GLTFLoader.js net::ERR_ABORTED 404 (Not Found)
问题根源
- 资源路径无效:本地服务器不会直接暴露
node_modules目录,直接引用该路径必然404;main.js的实际位置可能和HTML中声明的路径不匹配。 - 模块加载方式冲突:混用普通脚本和ES模块导致MIME类型错误;TypeScript编译成的CommonJS格式代码,浏览器无法识别
require语法。 - 模型托管问题:GLB模型的路径未被服务器正确托管,导致加载失败。
分步解决方案
1. 替换依赖引入方式,放弃直接引用node_modules
浏览器无法直接访问node_modules,改用CDN引入Three.js资源,或者用打包工具(如Vite、Webpack)处理依赖。以下是CDN方案的修改代码:
<body> <header> <script> async function fetchAndAppend(url, target) { const response = await fetch(url); const content = await response.text(); document.querySelector(target).innerHTML = content; } fetchAndAppend('./menu.html', 'header') .catch(error => { console.error('An error occurred:', error); }); </script> </header> <main> <!-- 用CDN引入Three.js核心与GLTFLoader,避免node_modules路径问题 --> <script type="module"> import * as THREE from 'https://cdn.skypack.dev/three@0.158.0'; import { GLTFLoader } from 'https://cdn.skypack.dev/three@0.158.0/examples/jsm/loaders/GLTFLoader.js'; // 场景初始化逻辑 const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.z = 5; const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // 加载GLB模型 const loader = new GLTFLoader(); // 确保模型放在服务器可访问目录,比如根目录下的public文件夹 loader.load('./public/WebPSRV4.glb', function (gltf) { const model = gltf.scene; scene.add(model); function animate() { requestAnimationFrame(animate); renderer.render(scene, camera); } animate(); }, function (xhr) { console.log((xhr.loaded / xhr.total) * 100 + '% loaded'); }, function (error) { console.error('An error occurred', error); }); </script> </main> </body>
2. 修正资源路径
- 将GLB模型移到服务器根目录下的
public文件夹(确保服务器托管该目录),路径改为相对路径./public/WebPSRV4.glb,避免绝对路径导致的跨目录访问问题。 - 移除原有
main.js和node_modules的脚本引用,改用上述内联模块脚本,或编译后的ES模块文件。
3. 规范TypeScript编译(若继续使用TS)
如果坚持用TypeScript,需将代码编译为浏览器可识别的ES模块:
- 在
tsconfig.json中配置:
{ "compilerOptions": { "module": "ESNext", "target": "ESNext", "outDir": "./dist", "strict": true } }
- 编译后生成的
main.js会在dist目录,HTML中引用方式:
<script type="module" src="./dist/main.js"></script>
- TS文件中改用ES模块导入:
import * as THREE from 'three'; import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'; // 后续逻辑不变
4. 确保本地服务器正确托管资源
如果使用http-server,启动时指定根目录:
http-server ./ -p 8081
确保所有静态资源(HTML、JS、GLB)都在该根目录下可访问。
验证步骤
- 启动本地服务器,访问
http://localhost:8081。 - 打开浏览器控制台,检查是否还有404或MIME类型错误。
- 确认GLB模型是否成功渲染到页面。
内容的提问来源于stack exchange,提问作者Tomas Salazar
相关产品推荐
相关产品推荐

