在前端项目构建过程中,同时生成压缩和非压缩版本的前端资源是很多团队的常规需求,压缩后的资源体积更小,适合生产环境部署,非压缩资源保留完整格式,方便开发阶段调试和线上问题排查。Webpack 5作为目前广泛使用的前端构建工具,通过合理的配置就能实现这个需求,不需要额外编写复杂的脚本。

前置环境准备
首先确保本地已经安装了Node.js环境,建议版本在14.0.0及以上,然后初始化项目并安装Webpack 5相关依赖:
# 初始化项目 npm init -y # 安装webpack和webpack-cli核心依赖 npm install webpack webpack-cli --save-dev # 安装处理JS的babel相关依赖(如果需要转译ES6+语法) npm install babel-loader @babel/core @babel/preset-env --save-dev # 安装css相关处理依赖(如果项目包含样式文件) npm install style-loader css-loader --save-dev # 安装压缩插件,webpack5内置了JS压缩能力,这里额外安装css压缩插件 npm install css-minimizer-webpack-plugin --save-dev
核心配置思路
要实现同时生成两种资源,核心思路是通过Webpack的output配置区分文件命名,结合optimization配置控制压缩行为,还可以通过环境变量或者不同的配置入口来区分两种构建模式。以下是具体的实现步骤。
基础配置文件结构
在项目根目录创建webpack.config.js文件,基础结构如下:
const path = require('path');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
module.exports = {
// 入口文件,根据项目实际情况调整
entry: './src/index.js',
// 模块处理规则
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
},
// 插件配置
plugins: [],
// 优化配置
optimization: {
minimizer: [
// 压缩CSS的插件
new CssMinimizerPlugin()
]
}
};区分压缩和非压缩资源输出
我们可以通过给输出文件添加不同的后缀来区分两种资源,比如非压缩文件命名为[name].js,压缩文件命名为[name].min.js,具体配置如下:
module.exports = {
// 其他配置保持不变
output: {
// 输出目录,根据需求调整
path: path.resolve(__dirname, 'dist'),
// 文件名根据是否压缩添加不同后缀,这里先写基础规则,后续通过环境变量控制
filename: (pathData) => {
// 判断是否为压缩模式,后续会传入对应参数
const isMin = process.env.BUILD_MIN === 'true';
return isMin ? '[name].min.js' : '[name].js';
},
// 清理旧的输出文件
clean: true
},
// 开发环境不开启压缩,生产环境开启
mode: process.env.NODE_ENV || 'development',
// 如果是压缩模式,开启optimization的压缩配置
optimization: {
// 只有压缩模式才压缩代码
minimize: process.env.BUILD_MIN === 'true',
minimizer: [
new CssMinimizerPlugin()
]
}
};配置运行脚本
在package.json的scripts中添加对应的运行命令,分别触发两种构建:
{
"scripts": {
"build:normal": "BUILD_MIN=false NODE_ENV=development webpack",
"build:min": "BUILD_MIN=true NODE_ENV=production webpack",
"build": "npm run build:normal && npm run build:min"
}
}同时生成两类资源的优化方案
上面的方式需要运行两次构建命令,也可以通过一次配置同时生成两种资源,这种方式适合不需要频繁切换构建模式的场景,配置如下:
const path = require('path');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
module.exports = [
// 非压缩资源配置
{
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
mode: 'development',
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: 'babel-loader'
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
},
optimization: {
minimize: false
}
},
// 压缩资源配置
{
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.min.js'
},
mode: 'production',
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: 'babel-loader'
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
},
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin()
]
}
}
];配置验证与注意事项
完成配置后,运行npm run build命令,就可以在dist目录下看到同时生成的压缩和非压缩资源。需要注意以下几点:
- 如果项目包含图片、字体等其他静态资源,需要额外添加对应的loader处理,比如
url-loader或者asset模块。 - 非压缩资源建议保留source map方便调试,可以在对应配置中添加
devtool: 'source-map'配置。 - 压缩资源的source map可以设置为
hidden-source-map,避免生产环境暴露源码信息。 - 如果项目使用了TypeScript,需要替换js相关的loader为
ts-loader,并添加对应的ts配置。
常见问题排查
如果构建后没有生成对应的资源,可以先检查以下几点:
- 入口文件路径是否正确,确保
src/index.js文件存在。 - 环境变量是否正确传入,运行命令时可以通过
echo $BUILD_MIN查看变量值。 - 依赖是否安装完整,缺少loader或者插件会导致构建失败。
- 输出目录权限是否正常,避免因为权限问题无法写入文件。