由于第三方 js 文件变换的频率不是很大,所以利用 webpack 的commonChunkPlugin把第三方包打包到一起,但是发现每次改动业务文件的时候,第三方 vendor 文件会重新打包,如果输入文件名为[name].[chunkhash].js的话,可以看到每次都会输出新的文件,虽然在线上可以把 vendor 的 chunkhash 去掉来实现缓存效果,但是在开发和打包的时候编译速度还是多多少少会受影响。

dll 定义

DLL(Dynamic Link Library)文件为动态链接库文件,又称“应用程序拓展”,是软件文件类型。在 Windows 中,许多应用程序并不是一个完整的可执行文件,它们被分割成一些相对独立的动态链接库,即 DLL 文件,放置于系统中。当我们执行某一个程序时,相应的 DLL 文件就会被调用。一个应用程序可使用多个 DLL 文件,一个 DLL 文件也可能被不同的应用程序使用,这样的 DLL 文件被称为共享 DLL 文件。

DllPlugin

DllPlugin 可以把第三方文件打包单独的文件,例如 vendor.dll.js,然后把相关的模块路径写到 manifest.json 文件,实现一次编译多次使用。

// webpack.dll.config.js
const webpack = require('webpack');
const path = require('path');
const vendors = ['react', 'react-dom', 'jquery'];
module.exports = {
// devtool: 'source-map',
entry: {
vendor: vendors,
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name]_[hash].dll.js',
library: '[name]_[hash]',
},
plugins: [
new webpack.DllPlugin({
path: path.join(__dirname, 'dist/manifest.json'),
name: '[name]_[hash]',
}),
],
};

在控制台执行

webpack --config webpack.dll.config.js

文件夹 dist 生成manifest.jsonvendor_950817b068aac369aa25.dll.js两个文件

DllReferencePlugin

对生成的 dll 文件,我们需要在打包的时候通过DllReferencePlugin引入

// webpack.config.js
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin');
module.exports = {
devtool: 'source-map',
entry: {
index: './src/js/index.js',
},
output: {
filename: 'js/[name].[chunkhash].js',
path: path.resolve(__dirname, 'dist'),
},
module: {
// loader
},
plugins: [
new webpack.DllReferencePlugin({
context: __dirname,
manifest: require(path.join(__dirname, 'dist', 'manifest.json')),
}),
new ExtractTextPlugin('style/[name].[chunkhash].css'),
new HtmlWebpackPlugin({
chunks: ['index'], // 只包含这个入口的文件
filename: `index.html`,
template: `src/index.html`,
}),
],
};

执行 webpack 打包,发现 HtmlWebpackPlugin 生成的 html 没有帮我们引入打包的 dll 文件,可以通过add-asset-html-webpack-plugin来引入

new AddAssetHtmlPlugin({
includeSourcemap: false,
filepath: path.join(__dirname, 'dist/*.dll.js'),
});

在生成的 html 文件就会在 script 标签引入我们的 dll.js 文件,提升打包速度