如何在document ready函数中使用模块文件解决未定义报错
问题:调用ES模块导出的配置项时报
kconfig is not defined错误 问题复现代码
配置文件 kconfig.js
const kconfig = (function () { function kconfig() { } kconfig.webApiUrl = "http://localhost/webapi/" return kconfig; })() export default kconfig;
页面代码 index.html
<script type="module" src="../../config/kconfig.js"></script> <script type="text/javascript"> $(function () { console.log('document ready...') console.log(kconfig.webApiUrl) //$.ajaxGet(kconfig.webApiUrl + 'api/hello/query/123') }); </script>
抛出错误
Uncaught ReferenceError: kconfig is not defined
补充说明:该配置文件此前在其他模块文件中可正常使用。
错误根因
- 加了
type="module"的script标签会被浏览器识别为ES模块,模块内的所有变量都属于模块私有作用域,不会自动挂载到全局window对象,因此后续普通脚本无法直接访问到模块内的kconfig变量。 - 此前在其他文件中能正常使用,是因为那些文件本身也是ES模块,通过
import语法显式导入了kconfig的导出值,符合模块的作用域规则。
解决方案
方案1:业务逻辑改用ES模块写法(推荐,符合模块化规范)
不需要污染全局作用域,直接在业务脚本中显式导入配置项即可,修改后的页面代码:
<script type="module"> // 直接在模块脚本中导入配置 import kconfig from '../../config/kconfig.js'; $(function () { console.log('document ready...') console.log(kconfig.webApiUrl) //$.ajaxGet(kconfig.webApiUrl + 'api/hello/query/123') }); </script>
注意:ES模块受同源策略限制,直接通过
file://协议打开本地html文件会加载失败,需要将代码部署在本地HTTP服务下访问。
方案2:显式将配置挂载到全局作用域
如果需要保留现有非模块脚本的写法,可以在模块加载时手动把kconfig挂到window对象上,修改后的页面代码:
<script type="module"> import kconfig from '../../config/kconfig.js'; // 手动暴露到全局 window.kconfig = kconfig; </script> <script type="text/javascript"> $(function () { console.log('document ready...') console.log(kconfig.webApiUrl) //$.ajaxGet(kconfig.webApiUrl + 'api/hello/query/123') }); </script>
ES模块默认会延迟执行,加上jQuery ready事件本身会等页面资源加载完成后再触发回调,不会出现变量未赋值就调用的时序问题。
方案3:将配置文件改为普通全局脚本
如果该配置不需要支持模块化导入,可以移除kconfig.js的模块化导出逻辑,作为普通脚本引入:
- 修改kconfig.js,删除最后一行的
export default kconfig; - 修改页面引入代码,去掉script标签的
type="module"属性:
<script src="../../config/kconfig.js"></script> <script type="text/javascript"> $(function () { console.log('document ready...') console.log(kconfig.webApiUrl) //$.ajaxGet(kconfig.webApiUrl + 'api/hello/query/123') }); </script>
这种写法下kconfig会直接注册为全局变量,普通脚本可直接访问。
内容的提问来源于stack exchange,提问作者Bes Ley
相关产品推荐
相关产品推荐

