前言
阅读完该篇文章大概需要2min。
-
vue-cli的出现,让我们省掉了配置webpack的时间。也就是说,一个不懂webpack的人,也能直接上手开发。比如file-loader, url-loader会提前为我们配置好。 -
性能方面,vue-cli也默认尽可能多的帮我们做了优化,比如cache-loader会在项目中预先做了配置。我们可以在控制台输入vue inspect > webpack.config.js ,即可在webpack.config.js查看cli预先定义好的基础配置。我们今天就在vue-cli搭建好的项目基础上聊一聊可优化的点。
项目源码
准备工作
- 通过vue-cli创建一个项目,我用的版本是vue-cli@4.5.13
- 安装几个常用的包: lodash, moment, element-ui, vue-router,vuex
量化指标
build的时间
speed-measure-webpack-plugin 插件可以在build的时候看到webpack的loader和plugin所用的时间,配置非常简单。如下:
module.exports = {
chainWebpack: config => {
config.plugin('speed')
.use(SpeedMeasureWebpackPlugin)
}
}
看一下效果 
build后包的大小以及数量
webpack-bundle-analyzer插件可以帮我们可视化的展示build时的每个包的大小以及依赖。
vue-cli也帮我们做了默认的配置,我只需要在build的后面加一个参数–report即可
{
"name": "dll-vue",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"report": "vue-cli-service build --report",
}
}
npm run report 之后,dist目录下就多了一个report.html文件,我们用浏览器打开这个文件看一下  可以清楚的看到基本上都是node_module中的包,只有右上角那个小蓝块是我们的vue代码
开始优化
减少第三包的大小(Moment为例)
moment这个库还是比较常用,但是这个库包含了一个很大的模块就是语言包,其实大部分的场景根本用不到需要适配到多国语言,所以我们只是载入中文包就够了。
webpack.ContextReplacementPlugin 这个插件可以帮我们做这件事,配置很简单。
module.exports = {
configureWebpack:{
plugins: [
new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /zh-cn/)
]
}
}
运行npm run report 我们来对比一下前后的大小, 小了有50kb。 
配合CDN加速(jQuery为例)
一般来说像jQuery这些第三方的包,我们采用CDN的方式来引入,像这样
<-- public/index.html -->
<script src="https://code.jquery.com/jquery-3.6.0.min.> js"></script>
但是在开发的过程中,我们也想要代码提示,则需要在文件内引入,像这样
import $ from 'jquery'
$('.today').text = 'today'
这就造成一个问题,build的时候就会将jquery再打包一次 我们可以配置externals 来达到build时忽略掉指定的依赖
module.exports = {
configureWebpack:{
externals: {
jquery: 'jQuery',
}
}
}
我们来对比一下前后的大小, 发现jquery消失了。 
阶段性效果预览(时间和大小)
 
拆包: DllPlugin 和 DllReferencePlugin(重点)
对于变化几率很小的一些第三方包,其实没必要build的时候都要打包一次, 可以把这些第三方包单独抽离出来,提前打包好。
webpack本身是要体现出模块间的依赖关系,当我们将一些包抽离出来后,维护之前的依赖关系就需要manifest.json 这个文件。让我们从接下来的实战中来学习它。
1. 新建一个配置文件webpack.dll.config.js(命名没有要求)
把第三方包单独抽离,防止一个包太多,我分成了两个,一个是vue相关的,一个是其他的
module.exports = {
mode: 'production',
entry: {
vue_vendor: ['vue/dist/vue.runtime.esm.js', 'vuex', 'vue-router', 'element-ui'],
other_vendor: ['lodash', 'moment']
},
output: {
filename: '[name].dll.js',
path: path.resolve(__dirname, './public/dll'),
library: '[name]_[hash]'
},
plugins: [
new webpack.DllPlugin({
name: '[name]_[hash]',
path: path.resolve(__dirname, '[name].manifest.json')
})
]
}
2. 读取配置,并执行
为了方便,我们将读取该配置文件的命令写到package.json文件中,像这样。(需要安装webpack-cli)
{
.....
"scripts": {
.....
"dll": "webpack --config ./webpack.dll.config.js"
}
.....
}
执行npm run dll 后可以看到生成两个manifest文件,像这样 
3. 修改vue.config.js,引入依赖文件,并自动将dll下的文件插入到index.html中
module.exports = {
chainWebpack: config => {
config.plugin('vendorDll1')
.use(webpack.DllReferencePlugin, [
{
context: __dirname,
manifest: require('./other_vendor.manifest.json')
}
])
config.plugin('vendorDll2')
.use(webpack.DllReferencePlugin, [
{
context: __dirname,
manifest: require('./vue_vendor.manifest.json')
}
])
config.plugin('asset')
.use(AddAssetHtmlWebpackPlugin, [
[
{
filepath: path.resolve(__dirname, 'public/dll/vue_vendor.dll.js'),
outputPath: 'dll',
publicPath: '/dll'
},
{
filepath: path.resolve(__dirname, 'public/dll/other_vendor.dll.js'),
outputPath: 'dll',
publicPath: '/dll'
}
]
])
}
}
我们打包一下看一下效果
  
总结
|