DllPlugin优化探究

webpack版本:4.43.0

  1. 手动配置DllPlugin

DllPlugin是webapck内置的一款可以加快构建速度的插件,其主要优化思想就是用空间换取时间,对于某些不常更新依赖内容,如:vue、vuex、vue-router,UI库等,可以提前打包好,取名为’dll.js’为后缀的打包文件,后面再打包的时候就跳过原来的未打包代码,直接使用之前打包好的文件,依次减少构建速度。

首先要写一个dll的webpack配置文件,放在根目录或者自己新建一个build文件夹都行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
var path = require('path');
const DllPlugin = require('webpack/lib/DllPlugin');

/* 将特定的类库提前打包然后引入,不但能够极大减少打包时间,
也实现了将公共代码抽离成单独文件的优化方案,可以很大程度的减小打包之后的文件体积。 */

module.exports = {
// 你想要提前打包的类库的数组。注意 vue 要写成别名
entry: {
// 如果这些类库有版本更新了(一般很少更新),就需要重新执行 npm run dll 打包类库,再执行 npm run build 打包项目上线
// 分成多个包
vuebundle: [
'vue/dist/vue.esm.js',
'vuex',
'vue-router'
],
utils: [
'lodash',
'moment',
'jspdf',
'html2canvas'
],
uibundle: [
'element-ui',
'@gs-ui/gs-ui'
]
},
output: {
path: path.join(__dirname, '../public/js'), // 打包后文件输出的位置,放到项目根目录的 public/js 下
filename: '[name].dll.js', // 打包后的文件名 vendor.dll.js
library: '[name]_library'
// vendor.dll.js 中暴露出的全局变量名,主要是给 DllPlugin 中的 name 使用。
// 所以这里需要和 webpack.DllPlugin 中的 name: '[name]_library', 保持一致。
},
plugins: [
new DllPlugin({
// manifest.json 生成的文件夹及名字,也就是让它生成在了根目录下
path: path.join(__dirname, './[name]-manifest.json'),
// 和 output.library 保持一致即可
name: '[name]_library',
// manifest 文件中请求的上下文,默认为本文件的上下文
context: __dirname
})
// 这里可以使用 UglifyJsPlugin 插件压缩代码
]
};

在vue.config.js里增加plugin配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const DllReferencePlugin = require('webpack/lib/DllReferencePlugin');
...
configureWebpack: {
plugins: [
// 此插件用于加速打包速度
// new HardSourceWebpackPlugin()

// 用于指定对应的json
new DllReferencePlugin({
manifest: require('./build/vuebundle-manifest.json')
}),
new DllReferencePlugin({
manifest: require('./build/utils-manifest.json')
}),
new DllReferencePlugin({
manifest: require('./build/uibundle-manifest.json')
})
]
},
...

在package.json里增肌一条dll命令

1
"dll": "webpack --config ./build/webpack.dll.conf.js", // 路径是dll配置放的路径

执行命令 npm run dll,因为我的dll配置里分成了三个包,所以我会得到三个json与三个dll.js文件,放在配置里指定存放的位置

1
2
3
4
5
6
7
8
// build 文件夹下
vuebundle-manifest.json
utils-manifest.json
uibundle-manifest.json
// public/js 文件夹下
vue.dll.js
utils.dll.js
ui.dll.js

最后一步,在index.html尾部引入三个dll.js文件

1
2
3
4
// index.html
<script src='./public/vue.dll.js'></script>
<script src='./public/utils.dll.js'></script>
<script src='./public/vue.dll.js'></script>

优点:

  • 可以加快构建速度,但其实加速的时间并不多。

缺点:

  • 配置步骤很麻烦,指定依赖更新时,需要手动执行命令进行更新
  • vue与react的脚手架已经去dll 配置,表示webpack4的打包性能足够好,不需要这个。(相关issues)[https://link.zhihu.com/?target=https%3A//github.com/vuejs/vue-cli/issues/1205]
  • 虽然可以指定依赖内容提前打包,但是开发环境下这些依赖依旧会打包进chunk里。
  1. 使用dll自动化配置插件:autodll-webpack-plugin

可以省去繁琐的dll配置,只需要在vue.config.js里增加如下配置即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
npm install autodll-webpack-plugin -D
...
const AutoDllPlugin = require('autodll-webpack-plugin');
...
new AutoDllPlugin({
inject: true, // 设为 true 就把 DLL bundles 插到 index.html 里
filename: '[name].dll.js',
context: path.resolve(__dirname, './'), // AutoDllPlugin 的 context 必须和 package.json 的同级目录,要不然会链接失败
entry: {
vue: [
'vue/dist/vue.esm.js',
'vuex',
'vue-router'
]
}
})
  1. 使用为模块提供中间缓存的插件hard-source-webpack-plugin,首次构建时间没有太大变化,但是第二次开始,构建时间会大大减少。配置也非常简单.
1
2
3
4
5
6
7
8
9
npm install hard-source-webpack-plugin -D
//webpack.config.js
var HardSourceWebpackPlugin = require('hard-source-webpack-plugin');
module.exports = {
//...
plugins: [
new HardSourceWebpackPlugin()
]
}
我想吃鸡腿!