【实战篇】基于vue-cli4创建的项目进行打包优化
前言
❝「阅读完该篇文章大概需要2min。」
❞
vue-cli的出现,让我们省掉了配置webpack的时间。也就是说,一个不懂webpack的人,也能直接上手开发。比如file-loader, url-loader会提前为我们配置好。
「性能方面」,vue-cli也默认尽可能多的帮我们做了优化,比如cache-loader会在项目中预先做了配置。我们可以在控制台输入
vue inspect > webpack.config.js
,即可在webpack.config.js查看cli预先定义好的基础配置。我们今天就在vue-cli搭建好的项目基础上聊一聊可优化的点。
项目源码
本文用到的项目代码https://github.com/equicy/vue-build-optimize
准备工作
通过vue-cli创建一个项目,我用的版本是vue-cli@4.5.13 安装几个常用的包: lodash, moment, element-ui, vue-router,vuex
量化指标
build的时间
❝
speed-measure-webpack-plugin
插件可以在build的时候看到webpack的loader和plugin所用的时间,配置非常简单。如下:// vue.config.js
module.exports = {
chainWebpack: config => {
config.plugin('speed')
.use(SpeedMeasureWebpackPlugin)
}
}「看一下效果」
❞
build后包的大小以及数量
❝webpack-bundle-analyzer插件可以帮我们可视化的展示build时的每个包的大小以及依赖。
vue-cli也帮我们做了默认的配置,我只需要在build的后面加一个参数--report即可
❞
// package.json
{
"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
这个插件可以帮我们做这件事,配置很简单。
// vue.config.js
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>但是在开发的过程中,我们也想要代码提示,则需要在文件内引入,像这样
// App.vue
import $ from 'jquery'
$('.today').text = 'today'这就造成一个问题,build的时候就会将jquery再打包一次 我们可以配置
❞externals
来达到build时忽略掉指定的依赖
// vue.config.js
module.exports = {
configureWebpack:{
externals: {
jquery: 'jQuery',
}
}
}
❝我们来对比一下前后的大小, 发现jquery消失了。
❞
阶段性效果预览(时间和大小)
拆包: DllPlugin 和 DllReferencePlugin(重点)
❝对于变化几率很小的一些第三方包,其实没必要build的时候都要打包一次, 可以把这些第三方包单独抽离出来,提前打包好。
webpack本身是要体现出模块间的依赖关系,当我们将一些包抽离出来后,维护之前的依赖关系就需要
❞manifest.json
这个文件。让我们从接下来的实战中来学习它。
1. 新建一个配置文件webpack.dll.config.js(命名没有要求)
❝把第三方包单独抽离,防止一个包太多,我分成了两个,一个是vue相关的,一个是其他的
❞
// webpack.dll.config.js
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)
// package.json
{
.....
"scripts": {
.....
"dll": "webpack --config ./webpack.dll.config.js"
}
.....
}执行
❞npm run dll
后可以看到生成两个manifest文件,像这样
3. 修改vue.config.js,引入依赖文件,并自动将dll下的文件插入到index.html中
module.exports = {
chainWebpack: config => {
// 多个manifest.json文件就需要写多次
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')
}
])
// 将dll下的文件自动插入到index.html中
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'
}
]
])
}
}
我们打包一下看一下效果
总结
❝❞
可以从最后的图片中可以看到时间从6s优化到了3s,chunk包的大小从200kb压缩到了10kb。
这次我们主要针对三种情况做了优化,当然如果项目很大,可通过
happypack plugin
或者thread-loader
进行多线程打包。如果感兴趣可在开始代码仓库看到示例欢迎大家点赞评论