You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

迁移至Vite后栈式脚本执行时机异常导致函数未定义

Vite迁移后脚本调用报错的本质原因解析

核心差异:Vite与Webpack的脚本加载机制不同

Webpack打包后的脚本是同步执行的——浏览器解析到Webpack输出的<script>标签时,会立刻执行里面的代码,window.myfoo会被同步挂载到全局对象上,后续@push的脚本执行时,全局函数已经存在,自然能正常调用。

但Vite用的是原生ES模块加载,它生成的app.js脚本标签自带type="module"属性:

<script type="module" src="/assets/app.xxxx.js"></script>

浏览器对type="module"的脚本会异步加载执行,哪怕这个脚本标签写在@push脚本的前面,它的执行时机也可能晚于后面的同步脚本。这就导致@push里直接调用myfoo()时,app.js里的代码还没跑完,window.myfoo还没被挂载,所以抛出"未定义"的错误。

为什么控制台/setTimeout调用能正常工作?

  • 控制台调用时,Vite的模块脚本已经加载执行完毕,window.myfoo已经存在于全局。
  • setTimeout会把函数调用放到任务队列,等当前同步代码全部执行完后再触发,此时Vite的模块脚本基本已经执行完成,所以能找到myfoo。

DOMContentLoaded能解决的原因

DOMContentLoaded事件会在页面DOM结构加载完成后触发,此时所有脚本(包括Vite的模块脚本)都已经加载执行完毕,window.myfoo已经挂载到全局,调用自然不会报错。

直观验证方法

查看页面最终渲染的HTML源码,你会发现Vite生成的app.js脚本标签带有type="module",而Webpack打包的脚本没有这个属性——这就是两者加载行为差异的直接体现。

内容的提问来源于stack exchange,提问作者Jeremy Belolo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 01:35:15