抽取公共代码
多页应用一般会重复多次使用部分公共代码,这样每次加载单页的时候,就会重复去加载这些公共代码,会造成以下问题:
1. 相同资源重复被加载,浪费用户流量,增加服务器成本。
2. 每个页面需要加载的资源太大,导致网页首屏加载缓慢,影响用户体验。
那么,如果将这些公共代码抽取出来,并让浏览器缓存起来,用户在请求资源的时候,可以直接读取缓存中的这些代码,这样就能解决以上问题。
如何抽取公共代码
- 现在存在如下文件结构:
other.js
↑
-------------
↑ ↑
a.js b.js
↓ ↓
-------------
↓
index.js
如上图,index.js和other.js都依赖了a.js和b.js,那么只需要将a.js和b.js抽离出来并打包成common.js,然后让index.js和other.js直接引用common.js即可.
- webpack.config.js配置
- 使用optimization的splitChunks属性,具体看代码注释
module.exports = {
optimization:{
splitChunks:{//分割代码块,如果只有一个入口,就不需要分割了,只有多页,才需要把公共的抽离出来
cacheGroups:{//缓存组
common:{//公共的模块
chunks:'initial',//刚开始就要抽离
minSize:0,//大小大于0字节的时候需要抽离出来
minChunks:2,//重复2次使用的时候需要抽离出来
}
}
}
},
...
}
这样就能够在一开始就将大小大于0字节的,并且使用2次以上的代码抽离出来,npm run build得到的文件为:
dist
|
----- common~index~other.js
|
----- index.js
|
----- other.js
|
----- index.html
这样,index.js和other.js都引用了抽离出来的公共代码commonindexother.js
如何抽离第三方库
- 假设在上面的基础上,index.js和other.js都引用了jquery库,那么这样来配置抽离第三方库
- vendor属性的配置,是用于抽取第三方库的(详看代码和注释)
module.exports = {
optimization:{
splitChunks:{//分割代码块,如果只有一个入口,就不需要分割了,只有多页,才需要把公共的抽离出来
cacheGroups:{//缓存组
common:{//公共的模块
chunks:'initial',
minSize:0,
minChunks:2,
},
vendor:{ test:/node_modules/,//把这个目录下符合下面几个条件的库抽离出来
chunks:'initial',//刚开始就要抽离
minSize:0,//大小大于0字节的时候需要抽离出来
minChunks:2,//重复2次使用的时候需要抽离出来
}
}
}
},
...
}
- 但是这样会存在问题——代码从上到下执行,会先执行common,然后执行vendor,而在执行common的时候,就把jquery抽离出来打包到跟a.js和b.js里面去了,后面的vendor就没有什么效果了。这并不是个好方案,我们最好是能够将库单独抽离出来,于是,可以这么操作:
- 在vendor添加权重属性:priority,将权重提高,使得先去抽离第三方库,再去抽离a.js和b.js
module.exports = {
optimization:{
splitChunks:{//分割代码块,如果只有一个入口,就不需要分割了,只有多页,才需要把公共的抽离出来
cacheGroups:{//缓存组
common:{//公共的模块
chunks:'initial',
minSize:0,
minChunks:2,
},
vendor:{
priority:1,//添加权重
test:/node_modules/,//把这个目录下符合下面几个条件的库抽离出来
chunks:'initial',//刚开始就要抽离
minSize:0,//大小大于0字节的时候需要抽离出来
minChunks:2,//重复2次使用的时候需要抽离出来
}
}
}
},
...
}
这样得到的结果为:
common~index~other.js 579 bytes
index.html 388 bytes
index.js 7.38 KiB
other.js 7.38 KiB
vendor~index~other.js 306 KiB
备注:其实以前有一个叫做commonChunkPlugins插件用于抽取公共代码的,现在webpack4.0有了自己的配置