一 前言
本文内容参考自 juejin.cn/post/684490… ,部分内容经过测试有修改。
测试系统:本文中的相关代码测试环境为macOS(2021-08-06)
日常的前端开发工作中,一般会配置两套构建环境,开发环境和生产环境。
webpack提供 mode 配置选项,告知 webpack 使用相应模式的内置优化。如果没有设置,webpack 会给 mode 的默认值设置为 production。
| 选项 | 描述 |
|---|---|
development | 会将 DefinePlugin 中 process.env.NODE_ENV 的值设置为 development. 为模块和 chunk 启用有效的名。 |
production | 会将 DefinePlugin 中 process.env.NODE_ENV 的值设置为 production。为模块和 chunk 启用确定性的混淆名称,FlagDependencyUsagePlugin,FlagIncludedChunksPlugin,ModuleConcatenationPlugin,NoEmitOnErrorsPlugin 和 TerserPlugin 。 |
none | 不使用任何默认优化选项 |
二 配置环境变量的多种方式
1. 使用命令行
写法一
- webpack 4
"scripts": {
"dev": "webpack-dev-server",
"build": "webpack"
},
- webpack 5
"scripts": {
"dev": "webpack server",
"build": "webpack"
},
- 以上 script 脚本,可以在任意模块内通过 process.env.NODE_ENV 获取当前的环境变量
- 但无法在 node 环境(webpack 配置文件中)下获取当前的环境变量
webpconk.config.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
console.log(`webpack 打印 process.env.NODE_ENV: ${process.env.NODE_ENV}\n`);
// webpack 打印 process.env.NODE_ENV: undefined
module.exports = {
entry: {
index: "./src/index.js",
},
output: {
path: path.resolve(__dirname, "./build"),
filename: "[name].js",
},
...
};
src/index.js
console.log(`index 打印 process.env.NODE_ENV: ${process.env.NODE_ENV}\n`)
// yarn dev
// webpack4 index 打印 process.env.NODE_ENV: development
// webpack5 index 打印 process.env.NODE_ENV: production
// yarn build
// webpack4 index 打印 process.env.NODE_ENV: production
// webpack5 index 打印 process.env.NODE_ENV: production
写法二
- webpack4
"scripts": {
"dev2": "webpack-dev-server --mode=development",
"build2": "webpack --mode=production"
},
- webpack5
"scripts": {
"dev2": "webpack server --mode=development",
"build2": "webpack --mode=production"
},
- 以上 script 脚本,可以在任意模块内通过 process.env.NODE_ENV 获取当前的环境变量, 跟随命令行
--mode选项的值 - 但无法在 node 环境(webpack 配置文件中)下获取当前的环境变量
写法三
webpack4
"scripts": {
"dev3": "webpack-dev-server --env=development",
"build3": "webpack --env=production"
},
webpack5
"scripts": {
"dev3": "webpack server --env=development",
"build3": "webpack --env=production"
},
- 以上 script 脚本,在任意模块内通过 process.env.NODE_ENV 获取当前的环境变量,在开发模式下(web server),
--env不管是设置development或者production,webpack4始终返回development,webpack5始终返回production - 可以在 node 环境(webpack 配置文件中)下,通过函数获取当前环境变量
webpack.config.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
module.exports = (env) => {
console.log(`webpack 打印 env: `, env);
// yarn dev3 --env=development
// webpack4 webpack 打印 env: development
// webpack5 webpack 打印 env: { WEBPACK_SERVE: true, development: true }
// yarn dev3 --env=production
// webpack4 webpack 打印 env: production
// webpack5 webpack 打印 env: { WEBPACK_SERVE: true, production: true }
// yarn build3 --env=development
// webpack4 webpack 打印 env: development
// webpack5 webpack 打印 env: { WEBPACK_BUNDLE: true, WEBPACK_BUILD: true, development: true }
// yarn build3 --env=production
// webpack4 webpack 打印 env: production
// webpack5 webpack 打印 env: { WEBPACK_BUNDLE: true, WEBPACK_BUILD: true, production: true }
return {
entry: {
index: "./src/index.js",
},
output: {
path: path.resolve(__dirname, "./build"),
filename: "[name].js",
},
...
};
};
src/index.js
console.log(`index 打印 process.env.NODE_ENV: ${process.env.NODE_ENV}\n`)
// yarn dev3 --env=development
// webpack4 index 打印 process.env.NODE_ENV: development
// webpack5 index 打印 process.env.NODE_ENV: production
// yarn dev3 --env=production
// webpack4 index 打印 process.env.NODE_ENV: development
// webpack5 index 打印 process.env.NODE_ENV: production
// yarn build3 --env=development or --env=production
// webpack4 index 打印 process.env.NODE_ENV: production
// webpack5 index 打印 process.env.NODE_ENV: production
2. 使用 webpack mode 配置选项
- 和使用命令的写法二(--mode),是一样的结果
- 可以在任意模块内通过 process.env.NODE_ENV 获取当前的环境变量,跟随
mode配置选项 - 但无法在 node 环境(webpack 配置文件中)下获取当前的环境变量
webpack.config.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
console.log(`webpack 打印 process.env.NODE_ENV: ${process.env.NODE_ENV}\n`);
// webpack 打印 process.env.NODE_ENV: undefined
module.exports = {
mode: "development",
entry: {
index: "./src/index.js",
},
output: {
path: path.resolve(__dirname, "./build"),
filename: "[name].js",
},
...
};
src/index.js
console.log(`index 打印 process.env.NODE_ENV: ${process.env.NODE_ENV}\n`)
// mode: "development"
// index 打印 process.env.NODE_ENV: development
// mode: "production"
// index 打印 process.env.NODE_ENV: production
3. 使用 webpack.DefinePlugin
DefinePlugin 允许在 编译时 将你代码中的变量替换为其他值或表达式。
- 可以在任意模块内通过 process.env.NODE_ENV 获取当前的环境变量
- 但无法在 node 环境(webpack 配置文件中)下获取当前的环境变量
webpack.config.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const webpack = require("webpack");
console.log(`webpack 打印 process.env.NODE_ENV: ${process.env.NODE_ENV}\n`);
// webpack 打印 process.env.NODE_ENV: undefined
console.log(`webpack 打印 V_VERSION: ${V_VERSION}`);
// ReferenceError: V_VERSION is not defined
module.exports = {
entry: {
index: "./src/index.js",
},
output: {
path: path.resolve(__dirname, "./build"),
filename: "[name].js",
},
devServer: {
contentBase: path.join(__dirname, "dist"),
compress: false,
port: 8000,
},
// 插件
plugins: [
new webpack.DefinePlugin({
"process.env.NODE_ENV": JSON.stringify("development"),
V_VERSION: JSON.stringify("v1.0.0"),
}),
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
// 模板匹配
template: "./src/index.html",
filename: "index.html",
chunks: ["index"],
}),
],
};
src/index.js
console.log(`index 打印 process.env.NODE_ENV: ${process.env.NODE_ENV}\n`)
// index 打印 process.env.NODE_ENV: development
console.log(`index 打印 V_VERSION: ${V_VERSION}`)
// index 打印 V_VERSION: v1.0.0
4. 使用 cross-env 插件
写法一
webpack4
"scripts": {
"dev4": "cross-env NODE_ENV=development V_VERSION=v2.0.0 webpack-dev-server",
"build4": "cross-env NODE_ENV=production V_VERSION=v2.0.0 webpack"
},
webpack5
"scripts": {
"dev4": "cross-env NODE_ENV=development V_VERSION='v2.0.0' webpack server",
"build4": "cross-env NODE_ENV=production V_VERSION=v2.0.0 webpack"
},
- 可以在任意模块内通过 process.env.NODE_ENV 获取当前的环境变量,命令行NODE_ENV的值无论是development还是production,
webpack4在开发模式下(web server),值都为development,生产构建时值为production,webpack5环境变量的值跟随命令行NODE_ENV的值 - 可以在 node 环境(webpack 配置文件中)下获取当前的环境变量,跟随命令行NODE_ENV的值
webpack.config.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
console.log(`webpack 打印 process.env.NODE_ENV: ${process.env.NODE_ENV}\n`);
// yarn dev4 NODE_ENV=development
// webpack 打印 process.env.NODE_ENV: development
// yarn dev4 NODE_ENV=production
// webpack 打印 process.env.NODE_ENV: production
// yarn build4 NODE_ENV=development
// webpack 打印 process.env.NODE_ENV: development
// yarn build4 NODE_ENV=production
// webpack 打印 process.env.NODE_ENV: production
console.log(`webpack 打印 V_VERSION: ${V_VERSION}`);
// ReferenceError: V_VERSION is not defined
module.exports = {
entry: {
index: "./src/index.js",
},
output: {
path: path.resolve(__dirname, "./build"),
filename: "[name].js",
},
devServer: {
contentBase: path.join(__dirname, "dist"),
compress: false,
port: 8000,
},
...
};
src/index.js
console.log(`index 打印 process.env.NODE_ENV: ${process.env.NODE_ENV}\n`)
// yarn dev4 NODE_ENV=development
// webpack4 index 打印 process.env.NODE_ENV: development
// webpack5 index 打印 process.env.NODE_ENV: development
// yarn dev4 NODE_ENV=production
// webpack4 index 打印 process.env.NODE_ENV: development
// webpack5 index 打印 process.env.NODE_ENV: production
// yarn build4 NODE_ENV=development
// webpack4 index 打印 process.env.NODE_ENV: production
// webpack5 index 打印 process.env.NODE_ENV: development
// yarn build4 NODE_ENV=production
// webpack4 index 打印 process.env.NODE_ENV: production
// webpack5 index 打印 process.env.NODE_ENV: production
console.log(`index 打印 V_VERSION: ${V_VERSION}`)
// Uncaught ReferenceError: V_VERSION is not defined
写法二
webpack4
"scripts": {
"dev5": "cross-env NODE_ENV=development webpack-dev-server --mode development",
"build5": "cross-env NODE_ENV=production webpack --mode production"
},
webpack5
"scripts": {
"dev5": "cross-env NODE_ENV=development webpack server --mode development",
"build5": "cross-env NODE_ENV=production webpack --mode production"
},
- 可以在任意模块内通过 process.env.NODE_ENV 获取当前的环境变量,跟随命令行
--mode选项的值 - 可以在 node 环境(webpack 配置文件中)下获取当前的环境变量,跟随命令行NODE_ENV的值
webpack.config.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
console.log(`webpack 打印 process.env.NODE_ENV: ${process.env.NODE_ENV}\n`);
// yarn dev5 NODE_ENV=development --mode development
// webpack 打印 process.env.NODE_ENV: development
// yarn dev5 NODE_ENV=production --mode production
// webpack 打印 process.env.NODE_ENV: production
// yarn dev5 NODE_ENV=development --mode production
// webpack 打印 process.env.NODE_ENV: development
// yarn dev5 NODE_ENV=production --mode development
// webpack 打印 process.env.NODE_ENV: production
// yarn build5 NODE_ENV=development --mode development
// webpack 打印 process.env.NODE_ENV: development
// yarn build5 NODE_ENV=production --mode production
// webpack 打印 process.env.NODE_ENV: production
// yarn build5 NODE_ENV=development --mode production
// webpack 打印 process.env.NODE_ENV: development
// yarn build5 NODE_ENV=production --mode development
// webpack 打印 process.env.NODE_ENV: production
module.exports = {
entry: {
index: "./src/index.js",
},
output: {
path: path.resolve(__dirname, "build"),
filename: "[name].js",
},
...
};
src/index.js
console.log(`index 打印 process.env.NODE_ENV: ${process.env.NODE_ENV}\n`)
// yarn dev5 NODE_ENV=development --mode development
// index 打印 process.env.NODE_ENV: development
// yarn dev5 NODE_ENV=production --mode production
// index 打印 process.env.NODE_ENV: production
// yarn dev5 NODE_ENV=development --mode production
// index 打印 process.env.NODE_ENV: production
// yarn dev5 NODE_ENV=production --mode development
// index 打印 process.env.NODE_ENV: development
// yarn build5 NODE_ENV=development --mode development
// index 打印 process.env.NODE_ENV: development
// yarn build5 NODE_ENV=production --mode production
// index 打印 process.env.NODE_ENV: production
// yarn build5 NODE_ENV=development --mode production
// index 打印 process.env.NODE_ENV: production
// yarn build5 NODE_ENV=production --mode development
// index 打印 process.env.NODE_ENV: development
总结
-
cross-env: 它是运行跨平台设置和使用环境变量(Node中的环境变量)的脚本。 -
--mode: 可以在任意模块内通过 process.env.NODE_ENV 获取当前的环境变量,但无法在 node 环境(webpack 配置文件中)下获取当前的环境变量 -
DefinePlugin: 允许在 编译时 将代码中的变量替换为其他值或表达式。可以在任意模块内通过 process.env.NODE_ENV 获取当前的环境变量,但无法在 node 环境(webpack 配置文件中)下获取当前的环境变量