使用CDN引入Three.js时出现THREE is not defined报错的问题求助
使用CDN引入Three.js时出现THREE is not defined报错的问题求助
这个问题我之前踩过一模一样的坑!核心原因是模块脚本的作用域是完全隔离的——你在type="module"的脚本里导入的THREE,只会存在于这个模块的局部作用域中,后面那个普通的<script>标签(没加type="module")根本访问不到这个变量,所以才会抛出“THREE is not defined”的错误。
给你两个可行的解决办法,优先推荐第一种:
方法一:把所有逻辑都放到模块脚本里(最规范)
这是符合ES模块设计逻辑的做法,既不会有全局变量污染的问题,也能顺利用上导入的Three.js。修改后的代码大概是这样:
<script type="importmap"> { "imports": { "three": "https://cdn.jsdelivr.net/npm/three@0.181.2/build/three.module.js" } } </script> <script type="module"> import * as THREE from 'three'; // 把之前普通脚本里的代码直接移到这里 const canvas = document.querySelector('#canvas'); const renderer = new THREE.WebGLRenderer({antialias: true, canvas}); </script>
方法二:手动将THREE暴露到全局作用域(仅特殊场景用)
如果因为某些特殊需求,必须在普通脚本里使用THREE,那可以在模块脚本里手动把THREE挂载到window对象上,这样全局就能访问到了:
<script type="importmap"> { "imports": { "three": "https://cdn.jsdelivr.net/npm/three@0.181.2/build/three.module.js" } } </script> <script type="module"> import * as THREE from 'three'; // 手动挂载到window对象,让全局脚本能访问 window.THREE = THREE; </script> <script> // 现在就能正常调用THREE了 const canvas = document.querySelector('#canvas'); const renderer = new THREE.WebGLRenderer({antialias: true, canvas}); </script>
最后再啰嗦一句:尽量优先用第一种方法,ES模块的作用域隔离是为了让代码更清晰、更易维护,全局变量多了很容易埋下各种奇怪的隐患~




