前言
在第一篇文章中,我们搭建了一个基于webpack5的vue3项目,现在我们就开始对这个乞丐版配置进行完善。 (这一期的完整代码可以在vue3-webpack5-templatetag0.0.2中看到)
v0.0.2 功能完善
区分环境
第一件事要做的就是区分环境,对此,我们需要按照cross-env这个依赖包
yarn add cross-env
然后对webpack.conf.js配置文件进行拆分,拆为webpack.base.conf.js、webpack.dev.conf.js、webpack.prod.conf.js三个文件,最后修改package.json中script的脚本
"scripts": {
"dev": "cross-env NODE_ENV=dev webpack serve --config ./build/webpack.dev.conf.js --color",
"build": "cross-env NODE_ENV=prod webpack --config ./build/webpack.prod.conf.js --color"
},
现在我们就可以通过执行不同的脚本命令,来使用不同环境的配置来构建应用,接下来我们再看看拆分后的配置是什么样的
配置拆分
首先是通用的webpack.base.conf.js,保留entry,resolve,module以及部分通用的plugin
const { VueLoaderPlugin } = require('vue-loader')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { resolve } = require('./utils.js')
module.exports = {
entry: {
app: resolve('src/main.js')
},
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: { '@': resolve('src') }
},
module: {
rules: [
{
test: /\.vue$/,
use: 'vue-loader'
},
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
cacheDirectory: true
}
},
include: [resolve('src')]
},
// ...其他rule省略
]
},
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: resolve('public/index.html'),
title: 'vue3-webpack-title'
}),
new VueLoaderPlugin()
]
}
然后是webpack.dev.conf.js,因为devServer中配置比较多,我们可以将这些配置单独放到build/config.js文件中进行统一管理,config文件内容如下
module.exports = {
dev: {
dev: {
proxyTable: {},
// Various Dev Server settings
host: 'localhost', // can be overwritten by process.env.HOST
port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
autoOpenBrowser: true,
errorOverlay: true,
poll: false
},
},
build: {}
}
接下来我们再看看webpack.dev.conf.js文件,首先需要合并webpack.base.conf.js,需要添加webpack-merge依赖包
yarn add webpack-merge -D
然后提取一些dev环境下特有配置即可,完整内容如下
const merge = require('webpack-merge')
const webpack = require('webpack')
const config = require('./config')
const baseWebpackConfig = require('./webpack.base.conf')
const HOST = process.env.HOST
const PORT = process.env.PORT && Number(process.env.PORT)
const devWebpackConfig = merge(baseWebpackConfig, {
module: {},
devServer: {
// http://[devServer.host]:[devServer.port]/[output.publicPath]/[output.filename] 进行访问
historyApiFallback: true,
hot: true,
client: {
overlay: config.dev.errorOverlay ? { warnings: false, errors: true } : false,
logging: 'none',
progress: true
},
compress: true,
host: HOST || config.dev.host,
port: PORT || config.dev.port,
open: config.dev.autoOpenBrowser,
proxy: config.dev.proxyTable
},
plugins: [new webpack.HotModuleReplacementPlugin()]
})
module.exports = devWebpackConfig
接下来就是生产环境,webpack.prod.conf.js,同样的,只保留相关配置即可
const merge = require('webpack-merge'
const baseWebpackConfig = require('./webpack.base.conf')
const { resolve } = require('./utils')
const config = require('./config')
const webpackConfig = merge(baseWebpackConfig, {
output: {
path: resolve('dist'),
filename: 'js/[name].[chunkhash].js',
publicPath: './',
clean: true
}
})
module.exports = webpackConfig
性能优化
性能优化的话主要是针对于打包,也就是webpack.prod.conf.js,我们一个一个来。
css抽离
这个使用官方推荐的MiniCssExtractPlugin即可
yarn add mini-css-extract-plugin -D
修改webpack.base.conf.js文件,在rule中引入MiniCssPlugin
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const isProdMode = process.env.NODE_ENV === 'prod'
module.exports = {
rules: [{
test: /\.(css|scss|sass)$/,
use: [
!isProdMode
? 'style-loader'
: {
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: '../'
}
},
'css-loader',
'postcss-loader',
{
loader: 'sass-loader',
options: { implementation: require('dart-sass') }
}
]
},
// ...]
}
接着在webpack.prod.conf.js(注意是prod文件,不是base文件)中,引入MiniCssEExtractPlugin
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
webpackConfig = merge(baseWebpackConfig, {
//...
plugins: [new MiniCssExtractPlugin({
filename: './css/[name].[contenthash].css',
chunkFilename: './css/[id].[contenthash].css'
}),// ...]
})
js/css压缩
这两个功能也是webpack5中已经有的,关于优化统一放到optimization中处理,首先添加TerserPlugin和CssMinimizerPlugin
yarn add css-minimizer-webpack-plugin terser-webpack-plugin -D
然后在webpack.prod.conf文件中添加optimization配置
const TerserPlugin = require('terser-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
webpackConfig = merge(baseWebpackConfig, {
//...
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
parallel: true,
extractComments: false,
terserOptions: {
compress: {
drop_console: true,
drop_debugger: true
}
}
}),
new CssMinimizerPlugin()
],
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all'
}
}
}
},
})
公共文件提取
这个比较简单,在webpack.prod.conf文件中添加splitChunks即可
webpackConfig = merge(baseWebpackConfig, {
//...
optimization: {
// ...
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all'
}
}
}
},
})
加快构建速度
这个需要利用webpack5新提供的cache属性
webpackConfig = merge(baseWebpackConfig, {
//...
cache: {
type: 'filesystem',
buildDependencies: {
config: [__filename]
},
version: process.env.NODE_ENV
}
})
简单解释一下这里面的配置信息,type可以设置为memory或file-sysytem,如果设置为memory,则不再需要其他的配置。buildDependencies指定构建过程的代码依赖性,
官方推荐设置为 [__filename],当你任何使用require()的module发生改变时Persistent Caching就会无效.。 version 则可以简单理解成一个外部变量,如果这个变量变了,那么缓存失效
总结
好了,在这篇文章中,我们对配置进行了不同的环境区分,并且对打包过程进行了优化,但是结束了吗?并没有,还有许多可以添加的配置和优化项等着我们完成,如果你已经消化完了这篇文章中的内容,那么开始下一篇吧