在实际开发中,我们经常需要针对生产环境和开发环境分别书写 webpack 配置。为了更好地适应这种需求,webpack 允许配置不仅可以是一个对象,还可以是一个函数。这样,开发者可以根据不同的环境返回不同的配置对象。
1. 使用函数作为配置
module.exports = env => {
return {
// 配置内容
};
};
在开始构建时,如果 webpack 发现配置是一个函数,会调用该函数,并将函数返回的对象作为配置内容。因此,开发者可以根据不同的环境返回不同的对象。
2. 传递环境变量
在调用 webpack 时,可以通过 --env
参数传递环境变量。这些环境变量会被传递给配置函数的 env
参数。
npx webpack --env abc # env: "abc"
npx webpack --env.abc # env: {abc: true}
npx webpack --env.abc=1 # env: {abc: 1}
npx webpack --env.abc=1 --env.bcd=2 # env: {abc: 1, bcd: 2}
3. 示例
假设我们有一个项目,需要根据环境变量 production
来区分生产环境和开发环境。
项目结构
my-project/
├── src/
│ ├── index.js
├── dist/
├── package.json
└── webpack.config.js
webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = env => {
const isProduction = env.production;
return {
mode: isProduction ? 'production' : 'development',
entry: './src/index.js',
output: {
filename: isProduction ? 'bundle.[contenthash:5].js' : 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
},
{
test: /\.css$/,
use: isProduction
? [MiniCssExtractPlugin.loader, 'css-loader']
: ['style-loader', 'css-loader']
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
}),
...(isProduction
? [new MiniCssExtractPlugin({ filename: '[name].[contenthash:5].css' })]
: [])
],
devServer: {
contentBase: './dist',
hot: true
}
};
};
安装依赖
npm install --save-dev webpack webpack-cli babel-loader @babel/core @babel/preset-env css-loader style-loader mini-css-extract-plugin html-webpack-plugin
运行构建
在 package.json
中添加两个脚本,分别用于开发环境和生产环境:
{
"scripts": {
"start": "webpack serve --env.development",
"build": "webpack --env.production"
}
}
然后运行:
npm start # 开发环境
npm run build # 生产环境
4. 解释
- 开发环境:使用
style-loader
将 CSS 插入到 DOM 中,使用HotModuleReplacementPlugin
实现热更新。 - 生产环境:使用
MiniCssExtractPlugin
将 CSS 提取到单独的文件中,使用[contenthash]
生成带有哈希值的文件名,以便浏览器缓存。
总结
通过本课程,你已经了解了如何使用函数作为 webpack 配置,以及如何通过 --env
参数传递环境变量。合理配置不同环境下的 webpack 配置可以提高开发效率和生产环境的性能。