详细讲一讲webpack部分的配置(入口和输出配置,模块处理配置(Loader),插件配置(Plugins),优化配置, 开发服务器配置,解析配置,性能配置
1. 入口和输出配置
module.exports = {
// 入口配置:指定打包的入口文件
entry: {
// 主应用入口
main: './src/main.js',
// 第三方库单独打包,有利于缓存
vendor: ['vue', 'vuex', 'vue-router'],
// 管理后台入口(多页面应用)
admin: './src/admin/index.js'
},
// 输出配置:指定打包后文件的输出规则
output: {
// 输出路径:绝对路径
path: path.resolve(__dirname, 'dist'),
// 输出文件名:
// [name]: entry中定义的key
// [chunkhash]: 根据内容生成的hash,内容不变hash不变
// [contenthash]: 针对文件内容级别的hash
filename: 'js/[name].[chunkhash:8].js',
// 异步加载的文件名
chunkFilename: 'js/[name].[chunkhash:8].chunk.js',
// 资源引用的公共路径,比如CDN
publicPath: process.env.NODE_ENV === 'production'
? 'https://cdn.example.com/'
: '/',
// 每次构建前清理输出目录
clean: true
}
}
2. 模块处理配置(Loader)
module: {
rules: [
// JavaScript/TypeScript处理
{
test: /\.(js|ts)$/, // 匹配文件
exclude: /node_modules/, // 排除文件
use: [
{
loader: 'babel-loader',
options: {
cacheDirectory: true, // 启用缓存
presets: ['@babel/preset-env'],
plugins: ['@babel/plugin-transform-runtime']
}
}
]
},
// Vue文件处理
{
test: /\.vue$/,
use: [
{
loader: 'vue-loader',
options: {
hotReload: true // 热重载
}
}
]
},
// 样式处理
{
test: /\.(css|scss)$/,
use: [
// 生产环境下抽取CSS文件
process.env.NODE_ENV === 'production'
? MiniCssExtractPlugin.loader
: 'style-loader',
{
loader: 'css-loader',
options: {
modules: { // CSS模块化
localIdentName: '[name]__[local]--[hash:base64:5]'
},
importLoaders: 2 // 之前有2个loader
}
},
'postcss-loader', // 自动添加前缀等
'sass-loader' // 处理scss
]
},
// 图片处理
{
test: /\.(png|jpe?g|gif|webp)$/,
type: 'asset', // webpack5的新资源模块
parser: {
dataUrlCondition: {
// 小于10kb转base64
maxSize: 10 * 1024
}
},
generator: {
// 输出文件名
filename: 'images/[name].[hash:8][ext]'
}
},
// 字体和其他文件
{
test: /\.(woff2?|eot|ttf|otf)$/,
type: 'asset/resource',
generator: {
filename: 'fonts/[name].[hash:8][ext]'
}
}
]
}
3. 插件配置(Plugins)
plugins: [
// HTML生成插件
new HtmlWebpackPlugin({
template: './public/index.html',
filename: 'index.html',
chunks: ['main', 'vendor'], // 指定要加载的chunks
minify: { // 压缩HTML
collapseWhitespace: true,
removeComments: true
},
// 注入变量
templateParameters: {
title: '应用标题',
BASE_URL: '/'
}
}),
// CSS提取插件
new MiniCssExtractPlugin({
filename: 'css/[name].[contenthash:8].css',
chunkFilename: 'css/[name].[contenthash:8].chunk.css'
}),
// 定义环境变量
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify(process.env.NODE_ENV),
VUE_APP_API: JSON.stringify(process.env.VUE_APP_API)
}
}),
// 复制静态资源
new CopyWebpackPlugin({
patterns: [
{
from: 'public',
to: 'assets',
globOptions: {
ignore: ['**/index.html'] // 忽略index.html
}
}
]
}),
// 进度条
new webpack.ProgressPlugin({
activeModules: false,
entries: true,
modules: true,
modulesCount: 500,
profile: false,
dependencies: true,
dependenciesCount: 10000
})
]
4. 优化配置
optimization: {
// 代码分割配置
splitChunks: {
chunks: 'all', // 对所有chunks都进行分割
minSize: 20000, // 生成chunk的最小体积
minChunks: 1, // 最少被引用次数
maxAsyncRequests: 30, // 最大异步请求数
maxInitialRequests: 30, // 最大初始化请求数
cacheGroups: { // 缓存组
// 第三方库分割
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10, // 优先级
reuseExistingChunk: true, // 复用已存在的chunk
name: 'vendors'
},
// 公共模块分割
common: {
minChunks: 2, // 最少被引用2次
priority: -20,
reuseExistingChunk: true,
name: 'common'
}
}
},
// 压缩配置
minimizer: [
// JS压缩
new TerserPlugin({
parallel: true, // 多进程压缩
terserOptions: {
compress: {
drop_console: true, // 移除console
drop_debugger: true // 移除debugger
}
}
}),
// CSS压缩
new CssMinimizerPlugin({
parallel: true
})
],
// 运行时chunk
runtimeChunk: {
name: 'runtime'
}
}
5. 开发服务器配置
devServer: {
// 端口
port: 3000,
// 自动打开浏览器
open: true,
// 启用热更新
hot: true,
// 启用gzip压缩
compress: true,
// 代理配置
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true,
pathRewrite: { '^/api': '' },
// https配置
secure: false
}
},
// 历史模式
historyApiFallback: true,
// 客户端日志等级
client: {
logging: 'info',
overlay: true // 显示错误
}
}
6. 解析配置
resolve: {
// 扩展名
extensions: ['.js', '.vue', '.json', '.ts'],
// 别名
alias: {
'@': path.resolve(__dirname, 'src'),
'vue$': 'vue/dist/vue.esm.js'
},
// 模块查找目录
modules: [
'node_modules',
path.resolve(__dirname, 'src')
]
}
7. 性能配置
performance: {
// 文件大小提示
hints: 'warning',
// 入口文件最大体积
maxEntrypointSize: 250000,
// 资源文件最大体积
maxAssetSize: 250000,
// 过滤需要监控的文件
assetFilter: function(assetFilename) {
return assetFilename.endsWith('.js');
}
}
这些配置的使用建议:
开发环境:
- 使用 eval-source-map 提升构建速度
- 启用热更新
- 禁用代码压缩
- 启用错误提示
生产环境:
- 启用代码分割和压缩
- 提取CSS文件
- 优化图片和字体
- 配置CDN
- 启用gzip压缩
通用优化:
- 合理使用缓存
- 优化模块查找路径
- 使用多进程构建
- 合理配置chunk分割
- 优化打包体积