Appearance
Webpack 配置详解
Webpack 配置是项目构建过程的核心,通过详细的配置可以控制打包行为、优化性能并满足各种开发需求。
基础配置结构
javascript
const path = require('path');
module.exports = {
// 基本配置
mode: 'development', // 模式
entry: './src/index.js', // 入口
output: { // 输出配置
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
// 模块处理规则
module: {
rules: [ // 加载器规则
// 规则配置
]
},
// 插件配置
plugins: [
// 插件实例
],
// 开发工具
devtool: 'source-map',
// 开发服务器
devServer: {
// 服务器配置
},
// 解析配置
resolve: {
// 模块解析规则
},
// 优化配置
optimization: {
// 优化策略
}
};
Entry 配置详解
单入口配置
javascript
module.exports = {
entry: './src/index.js'
// 等同于
// entry: {
// main: './src/index.js'
// }
};
多入口配置
javascript
module.exports = {
entry: {
// 多页面应用配置
home: './src/home.js',
about: './src/about.js',
contact: './src/contact.js'
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].bundle.js' // [name] 对应入口键名
}
};
高级入口配置
javascript
module.exports = {
entry: {
// 分离应用程序和第三方库入口
app: './src/app.js',
vendor: ['react', 'react-dom', 'lodash']
},
optimization: {
splitChunks: {
chunks: 'all'
}
}
};
Output 配置详解
基本输出配置
javascript
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'), // 输出目录的绝对路径
filename: 'bundle.js' // 输出文件名
}
};
高级输出配置
javascript
module.exports = {
entry: {
app: './src/app.js',
search: './src/search.js'
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash].js', // 使用内容哈希
chunkFilename: '[name].[contenthash].chunk.js', // 非入口 chunk 文件名
publicPath: '/assets/', // 公共路径
clean: true // 构建前清理输出目录 (Webpack 5)
}
};
Module 配置详解
Rule 配置
javascript
module.exports = {
module: {
rules: [
{
test: /\.css$/, // 匹配条件
use: [ // 使用的加载器(从右到左执行)
'style-loader',
'css-loader'
],
include: path.resolve(__dirname, 'src'), // 包含的目录
exclude: /node_modules/ // 排除的目录
},
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
},
include: path.resolve(__dirname, 'src')
}
]
}
};
复杂的 Rule 配置
javascript
module.exports = {
module: {
rules: [
// JavaScript 文件处理
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [
['@babel/preset-env', {
targets: {
browsers: ['last 2 versions']
}
}]
]
}
}
},
// CSS 文件处理
{
test: /\.css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: true, // 启用 CSS 模块
importLoaders: 1 // 在 css-loader 前应用的 loader 数量
}
},
'postcss-loader' // 后处理器
]
},
// 图片资源处理
{
test: /\.(png|jpe?g|gif|svg)$/i,
type: 'asset/resource', // Webpack 5 的新方式
generator: {
filename: 'images/[name].[hash][ext]' // 自定义输出路径
}
},
// 字体文件处理
{
test: /\.(woff|woff2|eot|ttf|otf)$/i,
type: 'asset/resource',
generator: {
filename: 'fonts/[name].[hash][ext]'
}
}
]
}
};
Resolve 配置详解
javascript
module.exports = {
resolve: {
// 解析模块时应该搜索的目录
modules: [
'node_modules',
path.resolve(__dirname, 'src')
],
// 自动解析确定的扩展
extensions: ['.js', '.jsx', '.json', '.ts', '.tsx'],
// 模块别名
alias: {
'@': path.resolve(__dirname, 'src'),
'@components': path.resolve(__dirname, 'src/components'),
'@utils': path.resolve(__dirname, 'src/utils'),
'react': path.resolve(__dirname, 'node_modules/react') // 强制使用特定版本
},
// 解析符号链接的真实路径
symlinks: false,
// 为模块创建别名来简化 require 或 import
fallback: {
'path': require.resolve('path-browserify')
}
}
};
Plugin 配置详解
javascript
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = {
plugins: [
// 清理输出目录
new CleanWebpackPlugin(),
// 生成 HTML 文件
new HtmlWebpackPlugin({
title: 'My App',
template: './src/index.html',
filename: 'index.html',
minify: {
removeComments: true,
collapseWhitespace: true
}
}),
// 提取 CSS 到单独文件
new MiniCssExtractPlugin({
filename: 'styles/[name].[contenthash].css',
chunkFilename: '[id].[contenthash].css'
}),
// 复制静态资源
new CopyWebpackPlugin({
patterns: [
{ from: 'public/', to: '.' }
]
})
]
};
DevServer 配置详解
javascript
module.exports = {
devServer: {
static: { // 静态文件服务配置
directory: path.join(__dirname, 'public'),
watch: true
},
compress: true, // 启用 gzip 压缩
port: 3000, // 端口号
open: true, // 自动打开浏览器
hot: true, // 启用热模块替换
historyApiFallback: true, // 支持 HTML5 History API
proxy: { // 代理配置
'/api': {
target: 'http://localhost:8080',
changeOrigin: true,
secure: false
}
},
client: {
overlay: true, // 显示编译错误
progress: true // 显示编译进度
}
}
};
Optimization 配置详解
javascript
module.exports = {
optimization: {
// 代码分割配置
splitChunks: {
chunks: 'all',
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
priority: 10,
chunks: 'all'
},
common: {
name: 'common',
minChunks: 2,
priority: 5,
chunks: 'all',
enforce: true
}
}
},
// 运行时代码分离
runtimeChunk: {
name: 'runtime'
},
// 代码最小化
minimize: true,
// 侧效应处理
sideEffects: false // 或者提供数组 ['*.css']
}
};
Mode 相关配置
Development 模式
javascript
// development 模式下的默认配置
module.exports = {
mode: 'development',
devtool: 'eval', // 启用快速源映射
optimization: {
minimize: false, // 不压缩
moduleIds: 'named', // 使用命名模块 ID
chunkIds: 'named' // 使用命名块 ID
}
};
Production 模式
javascript
// production 模式下的默认配置
module.exports = {
mode: 'production',
devtool: 'source-map', // 生成完整源映射
optimization: {
minimize: true, // 启用压缩
moduleIds: 'deterministic', // 使用确定性模块 ID
chunkIds: 'deterministic', // 使用确定性块 ID
mangleExports: 'deterministic' // 使用确定性导出混淆
}
};
环境特定配置
使用环境变量
javascript
// webpack.config.js
const isProduction = process.env.NODE_ENV === 'production';
module.exports = {
mode: isProduction ? 'production' : 'development',
devtool: isProduction ? 'source-map' : 'eval-source-map',
optimization: {
minimize: isProduction
}
};
多配置文件
javascript
// webpack.common.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
output: {
path: path.resolve(__dirname, 'dist'),
clean: true
}
};
// webpack.dev.js
const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');
module.exports = merge(common, {
mode: 'development',
devtool: 'inline-source-map',
devServer: {
static: './dist',
hot: true
}
});
// webpack.prod.js
const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');
module.exports = merge(common, {
mode: 'production',
devtool: 'source-map'
});
小结
Webpack 配置涉及多个方面,从基础的入口输出到高级的优化配置。通过合理配置这些选项,可以根据项目需求定制构建流程,提高开发效率和应用性能。理解每个配置项的作用和相互关系是掌握 Webpack 的关键。