用 webpack-merge 实现多环境配置的核心是“抽公共、分环境、再合并”,即提取共用配置到 webpack.common.js,分别编写 webpack.dev.js 和 webpack.prod.js 补充差异项,再通过 merge 安全合并,避免重复与覆盖错误。

用 webpack-merge 实现多环境配置,核心是“抽公共、分环境、再合并”。不是硬写三份完整配置,而是把共用部分(入口、输出路径、基础 loader、插件等)单独提出来,再为 dev 和 prod 各自补充差异项,最后安全合并。
第一步:安装并准备基础结构
先装依赖:
npm install webpack-merge --save-dev
项目根目录下建 config/ 文件夹,放三个配置文件:
-
config/webpack.common.js—— 公共配置(所有环境都用) -
config/webpack.dev.js—— 开发专属(热更新、source map、本地服务) -
config/webpack.prod.js—— 生产专属(压缩、哈希、Tree Shaking)
第二步:写公共配置(webpack.common.js)
只放真正通用的部分,比如入口、输出路径、基础模块规则、HTML 插件、别名等:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, '../dist'),
filename: '[name].[contenthash].js',
clean: true
},
resolve: {
extensions: ['.js', '.jsx', '.ts', '.tsx'],
alias: {
'@': path.resolve(__dirname, '../src')
}
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: 'babel-loader'
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
]
};
第三步:分别写开发和生产配置
两者都引入 common,再用 merge 叠加自己的配置。相同字段会以后面传入的为准(即 dev/prod 中的配置会覆盖 common 中同名项)。
开发配置(webpack.dev.js):
const { merge } = require('webpack-merge');
const common = require('./webpack.common');
module.exports = merge(common, {
mode: 'development',
devtool: 'eval-cheap-module-source-map',
devServer: {
port: 3000,
open: true,
hot: true,
historyApiFallback: true
}
});
生产配置(webpack.prod.js):
const { merge } = require('webpack-merge');
const common = require('./webpack.common');
const TerserPlugin = require('terser-webpack-plugin');
module.exports = merge(common, {
mode: 'production',
optimization: {
minimize: true,
minimizer: [new TerserPlugin({ terserOptions: { compress: true } })]
}
});
第四步:在 package.json 中定义脚本
让命令直接指向对应配置文件:
"scripts": {
"dev": "webpack serve --config config/webpack.dev.js",
"build": "webpack --config config/webpack.prod.js"
}
运行 npm run dev 或 npm run build 就能自动加载对应环境的完整配置。
注意:webpack-merge 不是简单 Object.assign,它对数组、插件、loader 等做了智能合并(比如 plugins 是追加而非覆盖),避免手动拼接出错。











