Vite中DOM脚本无法引用main.js变量的问题求助
核心原因
Vite默认将代码按ES模块处理,模块拥有独立作用域,变量不会自动暴露到全局window对象;另外脚本执行顺序如果没控制好,也会导致DOM脚本运行时目标变量还未被挂载到全局。
问题1:main.js声明的变量无法被DOM脚本访问
问题分析
你在main.js里用let getThis = 'Why does this not work';声明变量,一方面let声明的变量不会自动挂载到全局,另一方面ES模块的作用域隔离,DOM脚本(非模块脚本)无法直接访问模块内的变量。
解决办法
将变量显式挂载到window对象上,修改main.js:
window.getThis = 'Now it works';
之后在DOM脚本里就可以直接通过window.getThis或者getThis(全局作用域下)访问该变量。
问题2:挂载Bootstrap到window后仍报错bootstrap is not defined
问题分析
大概率是DOM脚本的执行时机早于main.js中挂载Bootstrap的代码。Vite的入口模块脚本是异步加载的,如果你用的是不带type="module"的普通DOM脚本,它会在模块脚本执行前就运行,此时window.bootstrap还未被赋值。
解决办法
推荐优先使用ES模块规范的方式,减少全局变量依赖;如果必须用全局变量,控制好执行顺序:
改用模块脚本(推荐)
将DOM脚本改为模块脚本,直接导入所需内容,无需挂载全局:<script type="module"> import * as bootstrap from 'bootstrap'; // 实例化Modal const modal = new bootstrap.Modal(document.getElementById('exampleModal')); </script>控制脚本执行顺序
给普通DOM脚本添加defer属性,确保它在DOM加载完成且模块脚本执行后再运行:<!-- 先加载main.js模块 --> <script type="module" src="/main.js"></script> <!-- 普通脚本加defer,延后执行 --> <script defer> const modal = new window.bootstrap.Modal(document.getElementById('exampleModal')); </script>用自定义事件触发执行
在main.js挂载完Bootstrap后触发自定义事件,DOM脚本监听事件后再执行逻辑:
main.js中:import * as bootstrap from 'bootstrap'; window.bootstrap = bootstrap; // 触发自定义事件 window.dispatchEvent(new Event('bootstrapReady'));DOM脚本中:
<script> window.addEventListener('bootstrapReady', () => { const modal = new bootstrap.Modal(document.getElementById('exampleModal')); }); </script>
总结
Vite基于ES模块生态,尽量遵循模块导入导出的规范来共享变量,避免滥用全局变量。如果必须使用全局变量,一定要确保挂载全局的代码先于使用该变量的DOM脚本执行。
内容的提问来源于stack exchange,提问作者Enrique

