webpack打包优化
webpack生产环境的打包优化手段有很多,其中code split是最重要的。
- 可以将
node_modules中代码单独打包一个chunk最终输出;
- 自动分析多入口
chunk中有没有公共的文件,如果有会单独打包为一个chunk;
import动态导入语法:能将某个文件单独打包。
通常情况下,用vue/cli生成的工程用默认的配置就可以达到一个自动的代码分割优化,但是多页面情况下并不完善。
默认配置
目前vue2.x的脚手架工程仍然使用webpack4,因此我们首先查看工程自带的生产环境配置,输入命令vue inspect --mode production >> webpack.prod.config.js,可以看到默认的代码分割配置如下:
optimization: {
splitChunks: {
cacheGroups: {
vendors: {
name: 'chunk-vendors',
test: /[\/]node_modules[\/]/,
priority: -10,
chunks: 'initial'
},
common: {
name: 'chunk-common',
minChunks: 2,
priority: -20,
chunks: 'initial',
reuseExistingChunk: true
}
}
},
如果是单页面的话其实没有什么问题,这个默认配置优化足够,只要在路由处配置动态加载即可。但是多页面的工程每个页面经常会引入不同的第三方库,chunk-vendors就会把所有的库都打包进去,造成体积过大,每个页面都会加载另一个页面的代码,而其并不需要。下面用最简单的一个多页面配置来演示下。
- 页面1使用
elmentui:
main.js
import Vue from 'vue'
import App from './App.vue'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import './plugins/directives'
Vue.use(ElementUI)
Vue.config.productionTip = false
new Vue({
render: h => h(App)
}).$mount('#app')
App.vue
<template>
<div id="app">
<el-button type="primary">使用ElementUi</el-button>
</div>
</template>
<style lang="less">
@import './assets/css/global.less';
#app {
font-family: @font-family-regular;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
</style>
- 页面2使用
ant design:
main2.js
import Vue from 'vue'
import App from './App2'
import Antd from 'ant-design-vue'
import 'ant-design-vue/dist/antd.css'
import './plugins/directives'
Vue.use(Antd)
Vue.config.productionTip = false
new Vue({
render: h => h(App)
}).$mount('#app')
App2.vue
<template>
<div id="app">
<a-button type="primary">使用Ant Design of Vue</a-button>
</div>
</template>
<script>
export default {
}
</script>
<style lang="less">
@import './assets/css/global.less';
#app {
font-family: @font-family-regular;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
#nav {
padding: 30px;
a {
font-weight: bold;
color: #2c3e50;
&.router-link-exact-active {
color: #42b983;
}
}
}
</style>
执行默认配置打包:
我们可以看到chunk-vendors巨大无比,当然因为为了方便这里都是全量引入的ui组件库,这个优化暂且不管,主要原因还是两个页面的两个组件库都打包进去了,这明显是不合理的。
修改默认配置
既然是打包了这两个页面的第三方库,那我们就修改配置为两个页面都引用的第三方库才打包进vendors中,
chainWebpack: config => {
config.optimization.splitChunks({
minSize: 1,
cacheGroups: {
vendors: {
name: 'chunk-vendors',
test: /[\/]node_modules[\/]/,
minChunks: 2, // 添加被引用次数
priority: -10,
chunks: 'initial'
},
common: {
name: 'chunk-common',
minChunks: 2,
priority: -20,
chunks: 'initial',
reuseExistingChunk: true
}
}
})
}
再试着打包一次:
可以看到chunk-vendors的体积大为减少,页面的chunk都增加了很多,也就是把各自引用的第三方库打包到了各自的chunk中去。
还有这边chunk-common也单独出现了,是因为这里修改了minSize为1,默认的是3000,因此最开始打包的时候就没单独打包出来,这里只是做个示例看一下,因为两个页面都引入了vue的公共指令,所以会被单独打包。
总结
webpack的线上优化手段还有很多,code split是最基础也是最强大的,但是也需要结合其他手段,比如这里示例每个chunk仍然很大,还可以用dll、externals等方法来处理。