为什么JS无法调用type为text/babel的脚本中定义的函数?
问题原因
type="text/babel"类型的脚本不会被浏览器原生直接解析执行,需要等待@babel/standalone库处理。而@babel/standalone对外部引入的text/babel脚本的处理是异步流程:需要先异步拉取脚本资源、完成转译后才会执行转译后的代码。- 你当前写的普通
type="text/javascript"内联脚本会在DOM解析到标签时立即执行,此时app.js还未完成拉取、转译、执行的流程,fnc函数还未挂载到全局作用域,因此会抛出未定义的错误。 - 额外说明:如果babel转译配置默认开启了模块封装,
app.js里定义的函数默认会处于局部作用域,不会暴露到全局window,即使执行时序正确也可能出现找不到函数的问题。
解决方法
方案1:调整调用脚本的类型(最便捷)
把调用fnc的内联脚本的type也改为text/babel,@babel/standalone会按脚本在DOM中的顺序依次处理所有text/babel类型的脚本,保证app.js执行完成后再执行调用逻辑:
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> <script src="/app.js" type='text/babel'></script> <!-- 修改type为text/babel --> <script type="text/babel"> fnc(); </script>
方案2:主动暴露函数到全局+调整调用时机
如果必须保留普通js类型的调用逻辑,可以做两个修改:
- 在
app.js中主动把需要全局调用的函数挂载到window对象上,避免作用域隔离问题:
window.fnc = function() { console.log('myname'); }
- 把调用逻辑放到页面资源加载完成的回调中,保证babel已经完成所有
text/babel脚本的处理:
<script type="text/javascript"> window.onload = function() { fnc(); } </script>
方案3:适配IE11的额外配置
如果需要保证转译后的代码兼容IE11,需要在引入@babel/standalone之前配置转译规则,指定适配目标:
<script> // 全局配置babel转译规则 window.Babel = { presets: [ [ "@babel/preset-env", { targets: { ie: "11" }, useBuiltIns: "usage", corejs: 3 } ] ] }; </script> <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
配置后babel会自动为IE11添加所需的语法兼容和polyfill,保证tensorflow相关代码可以正常运行。
内容的提问来源于stack exchange,提问作者YS K
相关产品推荐
相关产品推荐

