Esbuild全局模块引用报错:Uncaught ReferenceError问题解决
问题:Esbuild打包的全局变量在defer引入时内嵌脚本调用报错
场景与现象
- 用Esbuild 0.18.6打包
src/index.js,配置里指定globalName: 'xyz',将模块导出挂载到全局变量xyz上 - HTML中通过
<script defer src="dist/bundle.js"></script>引入打包脚本 - 页面按钮点击调用
xyz.myFunction()完全正常,但HTML内嵌脚本直接调用xyz.myFunction()时,抛出Uncaught ReferenceError: xyz is not defined - 移除
defer属性后,内嵌脚本调用恢复正常
原因分析
defer属性会让脚本异步加载,直到整个DOM解析完成后才执行(触发时机在DOMContentLoaded事件之前)。但内嵌脚本是浏览器解析到它的瞬间就立即执行,此时带defer的打包脚本还没加载执行,全局变量xyz尚未被创建,因此报错。
而按钮点击属于用户交互事件,触发时页面已加载完成,defer脚本早已执行完毕,xyz已存在,所以调用正常。
解决方法
- 移除
defer属性:最直接的方式,脚本会按顺序同步加载执行,内嵌脚本运行时xyz已存在 - 给内嵌脚本加加载完成监听:如果想保留
defer优化加载性能,可将内嵌代码放在DOMContentLoaded事件监听中,确保打包脚本执行后再调用:
document.addEventListener('DOMContentLoaded', () => { xyz.myFunction(); });
内容的提问来源于stack exchange,提问作者sirion1987
相关产品推荐
相关产品推荐

