ASP.NET Core项目使用webpack打包后jQuery、$未定义问题排查求助
问题根因定位
目前遇到的$ is not defined、jQuery打包顺序异常的核心问题来自两处配置错误,也能解释你之前尝试升级webpack、配置dependOn没有效果的原因:
- webpack默认采用模块沙箱隔离机制,所有打包的文件都被包裹在独立的模块闭包中,和传统浏览器下全局脚本的执行环境完全不同。jQuery源码会自动检测运行环境,如果识别到当前是CommonJS/ES模块环境,就不会主动把
jQuery、$变量挂载到全局window对象上——哪怕你把jQuery放在入口列表的第一位,它的变量也只在模块内部生效,全局环境根本访问不到。 - 你原本用来禁用AMD模块解析的
parser: {amd: false}配置,被错误嵌套在了SCSS的处理规则内部,根本没有对JS文件生效。这会导致jQuery被webpack按AMD模块逻辑解析,打乱模块执行的优先级,最终出现你看到的“jQuery总是最后加载”的异常排序。而你之前用的dependOn是多入口场景下用来拆分公共依赖的配置,单入口场景下根本没有适用的配置对象,自然调整无效。
分步修复方案
1. 修正模块解析规则,让AMD禁用配置对所有JS生效
把嵌套在SCSS规则里的parser配置抽出来,放到module的顶层,确保所有JS文件(包括jQuery)不会被AMD逻辑错误解析:
module: { // 顶层配置,对所有JS文件生效 parser: { amd: false }, rules: [ { test: /\.s[c|a]ss$/, use: [ // 删掉和MiniCssExtractPlugin冲突的style-loader MiniCssExtractPlugin.loader, 'css-loader', { loader: 'postcss-loader', options: { postcssOptions: { plugins: function () { let plugins = [require('autoprefixer')]; if (argv.mode === "production") { plugins.push(require('cssnano')); } return plugins; } } } }, 'sass-loader' ] } ] }
这里顺便修正一个现有配置的小冲突:你在SCSS的loader链里同时配置了style-loader和MiniCssExtractPlugin.loader,两个loader功能互斥——前者负责把CSS直接注入DOM的style标签,后者负责把CSS提取成独立文件。删掉style-loader即可,完全不影响自定义SCSS主题的开发需求。
2. 强制将jQuery暴露为全局变量,解决未定义报错
两种实现方式选其一即可,不需要额外安装新的npm依赖:
方式一:使用webpack内置ProvidePlugin自动注入(推荐)
在插件配置中添加规则,告诉webpack所有用到$、jQuery变量的地方,自动从jQuery模块导入,webpack会自动调整依赖顺序,把jQuery前置执行,从根本上解决打包顺序乱的问题:
const webpack = require('webpack'); plugins: [ new CleanWebpackPlugin(), new MiniCssExtractPlugin({ filename: bundleFileName + '.css' }), // 自动注入全局jQuery变量 new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery', 'window.jQuery': 'jquery' }) ]
方式二:在业务入口手动挂载全局变量
如果不想用ProvidePlugin,可以在site.js的最顶部手动完成jQuery的导入和全局挂载,同时把入口里直接写物理路径的引用改成模块化逻辑:
// site.js 文件顶部添加 import $ from 'jquery'; window.$ = $; window.jQuery = $; // 后续写你自己的业务JS代码
对应的entry配置可以简化,去掉之前冗余的jQuery物理路径引用:
entry: [ './wwwroot/js/site.js', './node_modules/bootstrap/dist/js/bootstrap.bundle.js', './wwwroot/scss/site.scss', './node_modules/jquery-validation/dist/jquery.validate.js', './node_modules/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.js' ]
因为site.js第一行就导入了jQuery,整个依赖链会自动把jQuery放到最前面执行,不会出现顺序错乱。
3. 验证效果
配置修改完成后重新执行打包命令,打开产物文件检查:
- 打包后的JS开头位置能看到jQuery的源码定义
- 浏览器控制台不再抛出
$ is not defined、jQuery is not defined的错误 - 页面中依赖jQuery的组件(比如bootstrap交互、前端表单验证)可以正常工作
内容的提问来源于stack exchange,提问作者Nicolas Van Damme
相关产品推荐
相关产品推荐

