跳到主要内容

Dynamic Link Library

2024年11月17日
柏拉文
越努力,越幸运

一、认识


Dynamic Link Library (动态链接库) ,简称 DLL: 通过 DllPluginDllReferencePlugin,将依赖分割成动态链接库。

DllPluginDllReferencePluginWebpack 提供的两个插件,用于优化构建性能,特别是在开发大型项目时。它们通过动态链接库(DLL)的方式,将项目的某些依赖分离为单独的构建产物,从而减少后续构建的时间。DllPluginDllReferencePlugin 用某种方法实现了拆分 bundles,同时还大幅度提升了构建的速度。DLL 一词代表微软最初引入的动态链接库。

在开发过程中,某些第三方依赖(如 ReactLodash 等)通常变化不频繁,而项目中的业务代码则频繁更新。如果每次构建都重新处理这些依赖,会浪费时间。DllPluginDllReferencePlugin 的设计目标就是解决这一问题。

1.1 DllPlugin

DllPlugin 此插件用于在单独的 webpack 配置中创建一个 dll-only-bundle。 此插件会生成一个名为 manifest.json 的文件,这个文件是用于让 DllReferencePlugin 能够映射到相应的依赖上。也就是说,DllPlugin 用于生成一个动态链接库文件,打包并输出不常变化的依赖,同时生成对应的映射清单(manifest 文件)。它的工作流程如下:

  1. 把不常变化的模块单独打包为动态链接库(DLL 文件)。

  2. 生成清单文件,记录动态链接库中包含的模块信息。

1.2 DllReferencePlugin

DllReferencePlugin 此插件配置在 webpack 的主配置文件中,此插件会把 dll-only-bundles 引用到需要的预编译的依赖中。也就是说,DllReferencePlugin 用于在主项目的 Webpack 配置中引入动态链接库。它读取 DllPlugin 生成的清单文件,避免重新打包这些依赖。

1.3 DllPlugin 和 DllReferencePlugin 工作流

  1. 构建动态库:运行 webpack.dll.js 配置文件,生成动态链接库文件和清单文件。

  2. 引用动态库:在主项目的 Webpack 配置中,通过 DllReferencePlugin 引用清单文件,告知 Webpack 这些模块已经存在于动态链接库中,不需要重新打包。

  3. 运行时引入 DLL 文件:通过 <script> 标签将 react.dll.js 文件引入到 HTML 中。

1.4 DllPlugin 和 DllReferencePlugin 构建优势

  1. 加快构建速度:第三方库在初次构建后会被缓存,后续只需处理业务代码,大幅缩短编译时间。

  2. 更好的缓存策略:动态链接库可以单独管理和更新,不会因为业务代码的改动而重新打包。

  3. 减少重复打包:主项目中只会引用动态链接库中的模块,而不会重复打包。

二、配置


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 版本兼容性

DllPluginDllReferencePlugin 对模块版本非常敏感,如果版本不一致可能导致运行时错误。

4.2 适合稳定依赖

不适合频繁变化的模块,因为频繁变化的模块需要重新生成动态链接库,失去性能优势。

4.3 动态链接库文件的引入

需要确保生成的 DLL 文件(如 react.dll.js)在运行时被加载。