DllPlugin DLLReferencePlugin
一、认识
Dynamic Link Library
(动态链接库) ,简称 DLL
: 通过 DllPlugin
和 DllReferencePlugin
,将依赖分割成动态链接库。
DllPlugin
和 DllReferencePlugin
是 Webpack
提供的两个插件,用于优化构建性能,特别是在开发大型项目时。它们通过动态链接库(DLL
)的方式,将项目的某些依赖分离为单独的构建产物,从而减少后续构建的时间。DllPlugin
和 DllReferencePlugin
用某种方法实现了拆分 bundles
,同时还大幅度提升了构建的速度。DLL
一词代表微软最初引入的动态链接库。
在开发过程中,某些第三方依赖(如 React
、Lodash
等)通常变化不频繁,而项目中的业务代码则频繁更新。如果每次构建都重新处理这些依赖,会浪费时间。DllPlugin
和 DllReferencePlugin
的设计目标就是解决这一问题。
1.1 DllPlugin
DllPlugin
此插件用于在单独的 webpack
配置中创建一个 dll-only-bundle
。 此插件会生成一个名为 manifest.json
的文件,这个文件是用于让 DllReferencePlugin
能够映射到相应的依赖上。也就是说,DllPlugin
用于生成一个动态链接库文件,打包并输出不常变化的依赖,同时生成对应的映射清单(manifest
文件)。它的工作流程如下:
-
把不常变化的模块单独打包为动态链接库(
DLL
文件)。 -
生成清单文件,记录动态链接库中包含的模块信息。
1.2 DllReferencePlugin
DllReferencePlugin
此插件配置在 webpack
的主配置文件中,此插件会把 dll-only-bundles
引用到需要的预编译的依赖中。也就是说,DllReferencePlugin
用于在主项目的 Webpack
配置中引入动态链接库。它读取 DllPlugin
生成的清单文件,避免重新打包这些依赖。
1.3 DllPlugin 和 DllReferencePlugin 工作流
-
构建动态库:运行
webpack.dll.js
配置文件,生成动态链接库文件和清单文件。 -
引用动态库:在主项目的
Webpack
配置中,通过DllReferencePlugin
引用清单文件,告知Webpack
这些模块已经存在于动态链接库中,不需要重新打包。 -
运行时引入
DLL
文件:通过<script>
标签将react.dll.js
文件引入到HTML
中。
1.4 DllPlugin 和 DllReferencePlugin 构建优势
-
加快构建速度:第三方库在初次构建后会被缓存,后续只需处理业务代码,大幅缩短编译时间。
-
更好的缓存策略:动态链接库可以单独管理和更新,不会因为业务代码的改动而重新打包。
-
减少重复打包:主项目中只会引用动态链接库中的模块,而不会重复打包。
二、配置
2.1 DllPlugin 生成动态链接库
DllPlugin
用于生成一个动态链接库文件,打包并输出不常变化的依赖,同时生成对应的映射清单(manifest
文件)。
// webpack.dll.js
const path = require('path');
const webpack = require('webpack');
module.exports = {
entry: {
// 将 react 和 react-dom 打包到一个动态链接库中
react: ['react', 'react-dom'],
},
output: {
path: path.resolve(__dirname, 'dll'),
filename: '[name].dll.js', // 输出的 DLL 文件
library: '[name]_dll', // 全局变量名
},
plugins: [
new webpack.DllPlugin({
name: '[name]_dll', // 与 library 保持一致
path: path.resolve(__dirname, 'dll/[name].manifest.json'), // 清单文件的路径
}),
],
};
运行以下命令构建 DLL
文件:
webpack --config webpack.dll.js
这会生成:
react.dll.js:打包的动态链接库文件。
react.manifest.json:记录库中模块信息的清单文件。
2.2 DllReferencePlugin 引入动态链接库
DllReferencePlugin
用于在主项目的 Webpack
配置中引入动态链接库。它读取 DllPlugin
生成的清单文件,避免重新打包这些依赖。
// webpack.config.js
const path = require('path');
const webpack = require('webpack');
module.exports = {
entry: './src/index.js', // 主项目入口
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
},
plugins: [
new webpack.DllReferencePlugin({
context: __dirname, // 与 DllPlugin 配置的 context 相同
manifest: require('./dll/react.manifest.json'), // 引用生成的清单文件
}),
],
};
三、场景
3.1 多次依赖未变
3.2 模块繁多的大型项目
四、问题
4.1 版本兼容性
DllPlugin
和 DllReferencePlugin
对模块版本非常敏感,如果版本不一致可能导致运行时错误。
4.2 适合稳定依赖
不适合频繁变化的模块,因为频繁变化的模块需要重新生成动态链接库,失去性能优势。
4.3 动态链接库文件的引入
需要确保生成的 DLL
文件(如 react.dll.js
)在运行时被加载。