如何强制Webpack DLL插件共享依赖库?解决jquery-validate重复引用问题
我之前也碰到过一模一样的问题!问题的核心在于jquery-validate的模块加载逻辑,加上Webpack DLL配置的一些细节没做到位,导致它没有复用你DLL里的jQuery,反而自己打包了一份。咱们一步步来排查解决:
1. 先检查你的DLL配置是否正确
首先得确保你的DLL确实把jQuery打包进去了,并且生成了正确的manifest文件供主项目引用。举个标准的DLL配置例子:
// webpack.dll.config.js const path = require('path'); const webpack = require('webpack'); module.exports = { entry: { vendor: ['jquery'] // 把jQuery加入DLL入口 }, output: { path: path.resolve(__dirname, 'dist'), filename: '[name].dll.js', library: '[name]_dll' // 必须和下面DllPlugin的name一致 }, plugins: [ new webpack.DllPlugin({ name: '[name]_dll', path: path.resolve(__dirname, 'dist/[name]-manifest.json') }) ] };
运行这个配置生成vendor.dll.js和vendor-manifest.json,这一步是基础,没做好后面全白搭。
2. 主项目配置要正确关联DLL
接下来主项目的Webpack配置里,必须用DllReferencePlugin引入刚才生成的manifest,告诉Webpack:"jQuery已经在DLL里了,别再打包它!",同时还要用ProvidePlugin全局注入jQuery——因为jquery-validate很依赖全局的$或jQuery变量,不然它可能会自己去require新的副本:
// webpack.config.js const webpack = require('webpack'); const path = require('path'); module.exports = { // ...你的其他配置(entry、output之类的) plugins: [ // 关联DLL manifest new webpack.DllReferencePlugin({ manifest: require('./dist/vendor-manifest.json') }), // 全局注入jQuery,让所有依赖它的库都能直接找到 new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery', 'window.jQuery': 'jquery' }) ], resolve: { // 强制所有对"jquery"的引用都指向同一个模块,避免版本不一致或重复打包 alias: { 'jquery': path.resolve(__dirname, 'node_modules/jquery') } } };
3. 理解jquery-validate的加载逻辑
你贴的代码里能看到它用了AMD的定义(__WEBPACK_AMD_DEFINE_FACTORY__这些标识),说明这个插件支持多种模块规范:
它的源码大概是这个结构:
(function( factory ) { if ( typeof define === "function" && define.amd ) { // AMD模式,加载"jquery"依赖 define( ["jquery"], factory ); } else if ( typeof module === "object" && module.exports ) { // CommonJS模式,require("jquery") module.exports = factory( require( "jquery" ) ); } else { // 浏览器全局模式,用window.jQuery factory( jQuery ); } }(function( $ ) { // ...插件核心代码 }));
Webpack处理这个模块时,如果你的配置没做好,它会把AMD里的"jquery"解析成一个新的模块,而不是DLL里的版本。上面的ProvidePlugin和resolve.alias就是为了把所有这些不同的引用方式,都统一指向DLL里的jQuery副本。
4. 验证是否解决问题
打包完成后,你可以做两个检查:
- 看主bundle的文件大小:如果之前包含jQuery,现在应该会小很多(jQuery大概几十KB)
- 打开主bundle的代码,搜索
jquery相关的模块ID,看是否和DLL里的一致,或者有没有重复的jQuery代码
按照上面的步骤来,基本就能解决jquery-validate复用DLL中jQuery的问题了。
内容的提问来源于stack exchange,提问作者mpen

