Webpack使用DllPlugin加速打包,并自动插入html

本文将指导如何使用DllPlugin加速webpack构建。

为什么

在Vue-webpack-multi工程中,如果想抽出公共部分,可以使用CommonsChunk插件完成。它会把vue等公共部分打包为vendor,每个页面引入vendor.js。但依然会存在一些问题:

  • 每次build会打包vendor,耗时
  • 有些module更新缓慢,有些module更新频繁,导致客户端经常下载很大的vendor.js

那么,如果有上述问题,可以引入DllPlugin抽出那些公用的,更新频度低的模块。思路类似与windows的dll文件。

怎么做

1、添加webpack.dll.config.js文件,这一步是为了告诉DllPlugin哪些文件需要抽出来,以及生成manifest.json配置文件。

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
const path = require('path');
const webpack = require('webpack');
module.exports = {
entry: {
vendor: ['vue/dist/vue.common.js','vue-router','vuex', 'fastclick', 'axios'] // 这里是哪些module需要抽出来
},
output: {
path: path.join(__dirname, '../static/js'),
filename: '[name].dll.js',
library: '[name]_library'
},
plugins: [
new webpack.DllPlugin({
path: path.join(__dirname, '.', '[name]-manifest.json'),
name: '[name]_library'
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
}
}),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
})
]
};

2、在webpack.prod.config.js 文件中添加引用:DllReferencePlugin

1
2
3
4
5
6
7
8
9
10
plugins: [
// ...
// 加入插件,让webpack使用dll
new webpack.DllReferencePlugin({
context: path.resolve(__dirname, '..'),
manifest: require('./vendor-manifest.json')
}),
// ...
]

3、在package.json文件中加入scripts:

1
"build:dll": "cross-env NODE_ENV=production webpack --config build/webpack.dll.conf.js --progress",

4、运行:

npm run build:dll

会在static/js目录下生成vendor.dll.js。到此可以把文件加入html文件使用了。

5、更进一步

是的,以上配置并不会在html中自动插入vendor.dll.js。那么,我们还需要另一个插件AddAssetHtmlPlugin来完成这个任务。

  • 首先引入依赖

    1
    npm i add-asset-html-webpack-plugin -D
  • 在webpack.prod.config.js 文件中添加引用:AddAssetHtmlPlugin

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    plugins: [
    // ...
    // 加入插件,让webpack使用dll
    new webpack.DllReferencePlugin({
    context: path.resolve(__dirname, '..'),
    manifest: require('./vendor-manifest.json')
    }),
    // 复制公共dll.js,并插入html
    new AddAssetHtmlPlugin([{
    filepath: path.resolve(__dirname,'../static/js/vendor.dll.js'), // 同webpack.dll.conf.js output
    outputPath: utils.assetsPath('js'),
    publicPath: path.posix.join(config.build.assetsPublicPath, 'static/js'),
    includeSourcemap: false,
    hash: true,
    }])
    // ...
    ]

    这时,再次运行

    1
    npm run build

    html已自动引入vendor.dll.js。

    1
    2
    3
    <script type="text/javascript" src="/live/static/js/vendor.dll.js?9052a4023ee8f3900f3a"></script>
    <script type="text/javascript" src="/live/static/js/vendor.9da0e0be7a97a0e0034e.js"></script>
    <script type="text/javascript" src="/live/static/js/embed/room.eb30321a94ba3c461902.js"></script>

参考: