在 webpack 中设置环境的方法有四种,如下:
- —mode 用来设置模块内的 process.env.NODE_ENV
- —env 用来设置 webpack 配置文件的函数参数
- cross-env 用来设置 node 环境的 process.env.NODE_ENV (推荐使用这种方法)
DefinePlugin 用来设置模块内的全局变量,也就是模块内的字符串替换
案例
从不同方面观察“环境设置”的行为:
分别在从 js 打包结果,
- 浏览器环境输出“process.env.NODE_ENV” 的值
- node (webpack) 环境输出“process.env.NODE_ENV ”的值。
注意:
- 浏览器环境没有 process 对象。
- 在浏览器环境输出 process.env.NODE_ENV 会被webpack 当作字符串惊醒替换。
在 webpack 中,输出是实实在在 NODE 环境中的 process 对象上的 env 中环境变量。
mode
控制 webpack 当前编译的环境,有三个值:
none 未指定。
- production 生产环境,webpack 会针对构建结果进行生产环境的优化,默认值。
- development 开发环境 webpack 不会对代码进行压缩。
package.json 配置
{
// 通过 mode 属性来控制 webpack 的模式,这边我们先选择 production
"scripts": {
"build": "webpack --mode development"
}
//"scripts": "webpack --mode production"
}
index 入口文件
/** ./src/index.js */
console.log(process.env.NODE_ENV)
webpack 配置文件
```javascript /* ./src/index.js / const path = require(‘path’); const { CleanWebpackPlugin } = require(‘clean-webpack-plugin’); const HtmlWebpackPlugin = require(‘html-webpack-plugin’); //…. console.log(process.env.NODE_ENV); module.exports = { //… }
<a name="o3VZh"></a>
### 结果
<a name="cUWnH"></a>
#### 文件打包结果
![image.png](https://cdn.nlark.com/yuque/0/2022/png/1584826/1656928953123-7aa2cc6e-98b2-475f-af0f-2b43269d9174.png#clientId=u30d71223-c1b9-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=747&id=u3e6da4b1&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1494&originWidth=2594&originalType=binary&ratio=1&rotation=0&showTitle=false&size=700711&status=done&style=none&taskId=ue549bc14-f899-461b-97da-896ed59020c&title=&width=1297)<br />代码没有被压缩,并且我们在 js 中的打印的 process.env.NODE_ENV 被替换成了我们设置的 development。
<a name="aVmsZ"></a>
#### 页面运行结果
![image.png](https://cdn.nlark.com/yuque/0/2022/png/1584826/1656926673470-eae03f9d-2f3f-4928-9231-629909edcdb1.png#clientId=u30d71223-c1b9-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=875&id=ua5de0d5f&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1750&originWidth=2880&originalType=binary&ratio=1&rotation=0&showTitle=false&size=565466&status=done&style=none&taskId=uf7a2054c-14e0-41e8-ae07-780a93b509e&title=&width=1440)<br />成功打印。
<a name="DT0NM"></a>
#### webpack 运行结果<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/1584826/1656927295653-631486a7-6987-463d-80aa-510097604000.png#clientId=u30d71223-c1b9-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=308&id=ua30ddb7e&margin=%5Bobject%20Object%5D&name=image.png&originHeight=616&originWidth=1712&originalType=binary&ratio=1&rotation=0&showTitle=false&size=255320&status=done&style=none&taskId=u5ddd8206-29af-4b79-a4b6-86cd4b86002&title=&width=856)
结果为 undefined,说明他并没有改变 NODE 的环境变量。
<a name="M9OLE"></a>
## env
webpack 配置文件的函数参数,需要如下使用,
<a name="pbuMA"></a>
### package.json 配置
```json
{
"scripts": {
"build":"webpack --env development"
}
//"scripts": "webpack --env production"
}
index 入口文件
/** ./src/index.js **/
console.log(process.env.NODE_ENV)
webpack 配置
/** ./webpack.config.js **/
let path = require('path');
//..
console.log(process.env.NODE_ENV);
module.exports = (env) => {
console.log(env);
return {
}
}
结果
文件打包结果
页面运行结果
webpack 运行结果
process.env.NODE_ENV 输出是 undefined ,env 输出是 { WEBPACK_BUNDLE: true, WEBPACK_BUILD: true, development: true }。
说明 env 参数只会改变 webpack 配置函数的参数。
如果想要配置 webpack 编译环境如下:
/** ./webpack.config.js **/
let path = require('path');
//..
console.log(process.env.NODE_ENV);
module.exports = (env) => {
console.log(env);
return {
mode: env.development ? 'development' : 'production',
}
}
cross-env
cross-env 是一款第三方的插件,可以用来同时设置 window 环境和 mac 环境的环境变量。
如下:
{
"scripts": {
"build": "cross-env NODE_ENV=development webpack"
}
}
文件打包结果
打包成功使用 development 编译环境,并且替换了浏览器环境中的 process.env.NODE_ENV 为 development 字符串。
页面运行结果
webpack 运行结果
process.env.NODE_ENV 成功打印 development。而函数参数则没有被设置。
如果想要根据环境判断编译模式就这么写,如下:
/** ./webpack.config.js **/
let path = require('path');
//..
console.log(process.env.NODE_ENV);
module.exports = (env) => {
console.log(env);
return {
mode: process.env.NODE_ENV ? 'development' : 'production',
}
}
DefinePlugin
DefinePlugin 用于设置模块内环境变量,也就是模块内的字符串替换
package.json 配置
{
"name": "t2",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "cross-env NODE_ENV=development webpack"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"clean-webpack-plugin": "^4.0.0",
"cross-env": "^7.0.3",
"css-loader": "^6.7.1",
"html-webpack-plugin": "^5.5.0",
"style-loader": "^3.3.1",
"webpack": "^5.73.0",
"webpack-cli": "^4.10.0"
}
}
index 入口文件
import './index.css';
console.log(process.env.NODE_ENV);
console.log(xxxx.env.NODE_ENV);
webpack 配置
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
const htmlPlugins = ['index', 'other'].map(chunkName => {
return new HtmlWebpackPlugin({
filename: `${chunkName}.html`,
inject: 'body',
chunks: [chunkName],
template: `./public/${chunkName}.html`
})
})
console.log(process.env.NODE_ENV)
module.exports = (env) => {
console.log(env)
return {
devtool: 'source-map',
entry: {
index: './src/index.js',
other: './src/other.js'
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash].js'
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
},
plugins: [
new webpack.CleanPlugin,
...htmlPlugins,
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
'xxxx.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
})
]
}
}
结果
页面运行结果
webpack 运行结果
此上事例说明,DefinePlugin 只是替换模块内的字符串,可以用来在代码中判断环境。而不会改变webpack的环境变量。