配置webpack ProvidePlugin后onclick内调用$报未定义错误是什么原因?
问题原因
这个问题本质是webpack模块化作用域和HTML行内脚本的全局作用域不互通导致的,具体原因分三点:
webpack.ProvidePlugin的作用范围仅限webpack打包的JS模块内部
ProvidePlugin的作用是:当webpack编译JS模块时,只要发现模块内出现未定义的$变量,就自动在模块顶部注入import $ from 'jquery'的逻辑,所以你的lazy_load函数内部的$('#load')可以正常运行,因为这部分代码在webpack处理的模块作用域内。
但HTML行内的onclick代码不属于webpack处理的JS模块,ProvidePlugin不会处理这部分代码里的$。- 行内
onclick事件的代码在全局window作用域执行
行内事件的代码运行时会找window对象下的$,但你当前的配置并没有把jQuery主动挂载到window上。你ProvidePlugin配置里写的"window.$": "jquery"不代表会主动把jQuery挂到window.$上,仅代表你如果在JS模块里写了window.$,webpack会把它替换为jQuery模块引用,不会主动修改全局对象。 - 断点时控制台
$可用是浏览器的内置功能
Chrome/Firefox等浏览器的开发者工具控制台默认内置了$辅助函数,等价于document.querySelector,和你引入的jQuery完全无关,所以不能用控制台的测试结果判断全局是否有jQuery的$。
解决方案
你可以任选一种方式修复:
- 主动把jQuery暴露到全局:在项目的入口JS文件(比如你这里的
js/main.js)顶部加一行代码:window.$ = window.jQuery = require('jquery'); - 放弃行内
onclick写法,改成在JS模块内绑定事件:
同时删除按钮标签里的// 加在main.js里即可 $('.btn-outline-warning').on('click', function() { lazy_load($("#load")); })onclick属性,这也是更符合前端规范的写法。 - 行内调用时避开使用
$,直接传DOM节点:<button type="button" class="btn btn-outline-warning" onclick='lazy_load(document.getElementById("load"))'>
内容的提问来源于stack exchange,提问作者Eugen Konkov
相关产品推荐
相关产品推荐

