如何在Webpack中不修改源码加载jquery-1.4.2模块并与jquery-3.x并行
我之前处理过类似的老版本jQuery和Webpack配合的问题,你遇到的cannot set property mylegacyplugin of undefined报错,本质是jQuery 1.4.2的模块导出逻辑和现代模块系统不兼容导致的:
jQuery 1.4.2发布时还没有CommonJS/AMD这类模块化规范,它默认只会把jQuery/$挂载到全局window对象上。而Webpack通过别名jquery1导入它时,模块本身并没有明确导出jQuery对象,所以imports-loader试图把插件的jQuery参数映射到jquery1时,拿到的是undefined,插件自然没法给undefined挂载方法。
你修改原jQuery文件的方法虽然可行,但不够优雅——修改第三方库文件会导致后续版本更新时需要重复操作,维护成本高。这里有两个更合适的解决方案:
方案1:用exports-loader配合imports-loader
先通过exports-loader让jQuery 1.4.2把全局的window.jQuery导出为模块的exports,这样imports-loader就能拿到正确的jQuery对象:
直接在require中使用
require("imports-loader?jQuery=jquery1!exports-loader?window.jQuery!app/some.jquery.mylegacyplugin");
配置到Webpack规则中(推荐)
在webpack.config.js里添加规则,一次性处理所有依赖jQuery 1.4.2的老插件,不用每次写长串loader:
module.exports = { // ...其他配置 module: { rules: [ // 处理jQuery 1.4.2,让它导出全局的jQuery对象 { test: require.resolve('jquery1'), // 替换成你jquery1别名对应的实际文件路径 use: 'exports-loader?window.jQuery' }, // 处理依赖jQuery 1.4.2的老插件,注入jQuery变量 { test: /some\.jquery\.mylegacyplugin\.js$/, // 匹配你的老插件文件 use: 'imports-loader?jQuery=jquery1' } ] } };
方案2:用Webpack ProvidePlugin全局注入
如果你的老插件依赖全局的jQuery/$变量,可以通过ProvidePlugin自动给所有模块注入jquery1:
const webpack = require('webpack'); module.exports = { // ...其他配置 plugins: [ new webpack.ProvidePlugin({ jQuery: 'jquery1', $: 'jquery1' }) ] };
之后直接引入老插件即可,不用额外的loader:
require("app/some.jquery.mylegacyplugin");
这两种方案都不用修改原jQuery文件,既能解决报错问题,也更符合模块化开发的最佳实践。
内容的提问来源于stack exchange,提问作者Marinos An

