导入变量时脚本重复执行 致双Canvas问题求助
模块重复加载导致THREE.Scene初始化两次的问题分析与解决
核心原因:模块被多次加载(而非ES模块本身重复执行)
ES模块规范明确,同一模块在同一应用中只会初始化一次,导出的是单例引用。你遇到的scene重复初始化,本质是main.js被当成了两个不同的模块加载,而非import操作导致代码重复执行。
常见触发场景:
- 相对路径不一致:比如部分文件用
import { scene } from '../main',另一部分用import { scene } from './main',构建工具会将这两个路径判定为不同模块,分别执行初始化代码。 - HTML与模块系统重复引入:在HTML中直接通过
<script src="./main.js" type="module"></script>引入main.js,同时其他模块又通过import加载它,会导致模块被加载两次。 - 构建工具配置冲突:比如webpack的
resolve配置未统一扩展名,或存在符号链接、路径别名冲突,导致模块解析重复。
验证方法
在main.js中添加一行打印代码,观察控制台输出次数:
// main.js console.log('main.js 执行了') export const scene = new THREE.Scene()
如果控制台打印两次,即可确认模块被重复加载。
解决方案
- 统一模块引用路径:确保所有import
main.js的地方使用完全一致的相对路径,或配置路径别名(如在vite/webpack中用@指向项目根目录,统一写为import { scene } from '@/main')。 - 避免双重引入:若使用模块系统管理依赖,不要在HTML中直接引入
main.js,通过入口模块(如index.js)统一导入所有依赖。 - 检查构建工具配置:确保构建工具的模块解析规则统一,比如webpack的
resolve.extensions包含常用扩展名(.js、.jsx等),避免因扩展名缺失导致解析为不同模块。
补充:全局变量能解决的原因
全局变量挂载在window对象上,是全局唯一的单例,无论模块加载多少次,都会复用同一个变量,因此不会出现重复初始化的问题。但这并非规范的模块管理方式,建议从模块加载的根源解决问题。
内容的提问来源于stack exchange,提问作者Elo Hell
相关产品推荐
相关产品推荐

