
本文详解如何通过 CDN 在现代浏览器中正确使用 ES 模块方式导入 Three.js 及其官方 STLLoader,避免常见语法错误与路径陷阱。
在 Three.js 生态中,STLLoader 并非独立发布的 NPM 包(如 stl-loader@2.3.0),而是作为 Three.js 官方示例模块(examples/jsm/)的一部分 维护和分发。这意味着:❌ 不能直接通过 import { STLLoader } from 'stl-loader' 导入第三方 UMD 库;✅ 必须从 three 的 jsm 目录下按路径导入官方维护的 ES 模块版本。
✅ 正确做法:统一使用 three 官方 ESM 生态
请将 <script type="importmap"> 中的 imports 配置精简并修正为:
<script type="importmap">
{
"imports": {
"three": "https://unpkg.com/three@0.154.0/build/three.module.js",
"three/addons/": "https://unpkg.com/three@0.154.0/examples/jsm/"
}
}
</script>⚠️ 注意:
- 不要单独引入 stl-loader(它不是标准 ESM,无默认/具名导出);
- three/addons/ 路径必须精确匹配(末尾 / 不可省略),这是 import { STLLoader } from 'three/addons/loaders/STLLoader.js' 能解析的前提。
✅ 完整可运行代码(已修复所有关键问题)
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<title>Three.js STL 加载示例</title>
<style>body { margin: 0; overflow: hidden; }</style>
</head>
<body>
<!-- ES Module Shims(兼容旧版浏览器,可选) -->
<script async src="https://unpkg.com/es-module-shims@1/dist/es-module-shims.js"></script>
<!-- Import Map:声明模块别名 -->
<script type="importmap">
{
"imports": {
"three": "https://unpkg.com/three@0.154.0/build/three.module.js",
"three/addons/": "https://unpkg.com/three@0.154.0/examples/jsm/"
}
}
</script>
<script type="module">
import * as THREE from 'three';
import { STLLoader } from 'three/addons/loaders/STLLoader.js'; // ✅ 正确路径!
// 场景基础设置
const scene = new THREE.Scene();
scene.background = new THREE.Color(0xcc0000);
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
document.body.appendChild(renderer.domElement);
// 光源(使材质可见)
const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
scene.add(ambientLight);
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
directionalLight.position.set(1, 1, 1);
directionalLight.castShadow = true;
scene.add(directionalLight);
// 加载 STL 模型
const loader = new STLLoader();
loader.load(
'https://raw.githubusercontent.com/mrdoob/three.js/master/examples/models/stl/binary/clock.stl', // 示例在线 STL
(geometry) => {
const material = new THREE.MeshPhongMaterial({
color: 0xaaaaaa,
specular: 0x111111,
shininess: 200
});
const mesh = new THREE.Mesh(geometry, material);
mesh.castShadow = true;
mesh.receiveShadow = true;
mesh.scale.set(10, 10, 10);
mesh.position.y = -2; // 微调避免穿底
geometry.center(); // 居中几何体原点
scene.add(mesh);
},
undefined,
(err) => console.error('STL 加载失败:', err)
);
// 渲染循环
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
animate();
// 响应式适配
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
</script>
</body>
</html>? 关键要点总结
- 路径即规范:STLLoader 的唯一标准 ESM 入口是 'three/addons/loaders/STLLoader.js',不可替换为其他 CDN 路径;
- 版本对齐:three 主包与 jsm 示例模块必须严格同版本(如 @0.154.0),否则可能因 API 变更导致报错;
- CORS 安全限制:本地直接双击打开 HTML 会因 file:// 协议触发跨域错误,请使用 live-server、VS Code Live Server 插件或部署到 HTTP 服务;
- 材质与光照:STL 文件仅含几何数据(无 UV、无材质),务必手动添加光照(AmbientLight + DirectionalLight)才能看到明暗效果;
- 调试建议:首次加载失败时,优先检查浏览器控制台 Network 标签页,确认 .stl 文件是否 200 成功返回,而非 404 或 CORS 错误。
遵循以上结构与规范,你就能稳定、高效地在纯 CDN 环境中加载任意二进制或 ASCII STL 模型——无需构建工具,开箱即用。










