前言
最近搞了个新项目,要搭个新环境,采用vue + es6 + webpack + babel技术栈,所以就将最近看到的关于webpack性能优化技术方案,包括dll以及happyPack等。写篇博客当做技术沉淀和积累吧。
实践
记得上一个上线的项目用webpack打包时间将近90s,项目是集成在jenkins上的,每次部署感觉都像页面死掉了一样,区区几十个业务模块和几百个依赖就耗费如此长时间,想想以后要是碰见大项目该咋办。刚刚建了个新项目试了试,仅仅简单引入了vue, vuex, axios, vue-router, vue-validator, moment几个模块,另外封装了几个组件,按照vue-cli生成的默认webpack配置打包要耗费19s,由于已经作了优化就没有截图,于是我就开始做优化了。
1、DllPlugin & DllReferencePlugin
一般打包第三方库我们会用CommonsChunkPlugin,三方库一般情况下是不会变的,但是每次部署的时候都得重新打包一次三方库,这样就造成了浪费,而DllPlugin可以轻松解决这个问题。
dll的意思大家应该都明白,意思就是dynamic-link library即windows系统中动态链接库,顾名思义webpack.DllPlugin的作用是将三方库打包一个动态链接库,避免多次重复打包。
首先新建一个配置文件webpack.dll.conf.js,先看看配置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
39var path = require('path')
var webpack = require('webpack')
var AssetsPlugin = require('assets-webpack-plugin')
function resolve(dir) {
return path.join(__dirname, '..', dir)
}
module.exports = {
entry: {
vendor: ['vue/dist/vue.esm.js', 'vuex', 'axios', 'vue-router', 'vue-validator', 'moment']
},
output: {
path: resolve('static'),
filename: '[name].dll.[chunkhash].js',
library: '[name]_library'
},
plugins: [
new webpack.ContextReplacementPlugin(
/moment[\/\\]locale$/,
/zh-cn/
),
new webpack.DllPlugin({
name: '[name]_library',
path: "./static/[name]-manifest.json",
context: path.join(__dirname, '..')
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
},
}),
// 生成指定js文件名的json,然后HtmlWebpackPlugin方便注入到index.html
new AssetsPlugin({
filename: 'dll.json',
path: './static'
})
]
}
webpack.base.conf.js1
2
3
4new webpack.DllReferencePlugin({
context: path.join(__dirname, '..'),
manifest: require("../static/vendor-manifest.json")
})
DllPlugin和DllReferencePlugin要结合着用,webpack.DllPlugin的作用是生成vendor-manifest.json和vendor.dll.js文件,vendor.dll.js就是我们的dll包。vendor-manifest.json是库文件的node_modle路径和webpack打包id的映射。webpack.DllReferencePlugin用于指导webpack打包业务代码时,遇到vendor-manifest.json的中库文件,利用vendor.dll.js暴露的全局函数进行处理,而不会把库文件也打包进来。
看看执行npm run dll之后的情况
vendor-manifest.json类似以下代码1
2
3
4
5
6
7
8
9
10
11
12
13
14{
"name": "vendor_library",
"content": {
"./node_modules/axios/lib/utils.js": {
"id": 0,
"meta": {}
},
"./node_modules/process/browser.js": {
"id": 1,
"meta": {}
},
...
}
}
2、HappyPack
HappyPack makes webpack builds faster by allowing you to transform multiple files in parallel.
HappyPack的作用就是并发执行各种loader,加快构建速度。
webpack.bas.conf.js1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22var HappyPack = require('happypack')
var threadPool = HappyPack.ThreadPool({
size: os.cpus().length
})
// 省略
plugins: [
new HappyPack({
id: 'js',
loaders: ['babel-loader?cacheDirectory=true'],
threadPool: threadPool
})
],
module: {
rules: [
{
test: /\.js$/,
loader: 'happypack/loader?id=js',
include: [resolve('src')],
exclude: /node_modules/
}
]
}
看看最终的构建情况吧,由原来的19s降到了6.7s,心情是不是感到很舒畅