在 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 配置

    1. {
    2. // 通过 mode 属性来控制 webpack 的模式,这边我们先选择 production
    3. "scripts": {
    4. "build": "webpack --mode development"
    5. }
    6. //"scripts": "webpack --mode production"
    7. }

    index 入口文件

    1. /** ./src/index.js */
    2. 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 = { //… }
  1. <a name="o3VZh"></a>
  2. ### 结果
  3. <a name="cUWnH"></a>
  4. #### 文件打包结果
  5. ![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。
  6. <a name="aVmsZ"></a>
  7. #### 页面运行结果
  8. ![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 />成功打印。
  9. <a name="DT0NM"></a>
  10. #### 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)
  11. 结果为 undefined,说明他并没有改变 NODE 的环境变量。
  12. <a name="M9OLE"></a>
  13. ## env
  14. webpack 配置文件的函数参数,需要如下使用,
  15. <a name="pbuMA"></a>
  16. ### package.json 配置
  17. ```json
  18. {
  19. "scripts": {
  20. "build":"webpack --env development"
  21. }
  22. //"scripts": "webpack --env production"
  23. }

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 {

  }
}

结果

文件打包结果

image.png
没有把编译环境设置成 development。

页面运行结果

image.png
同样是生产环境

webpack 运行结果

image.png
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"
  }
}

其他打印的地方与 env 一样

文件打包结果

image.png
打包成功使用 development 编译环境,并且替换了浏览器环境中的 process.env.NODE_ENV 为 development 字符串。

页面运行结果

image.png
development 生效成功

webpack 运行结果

image.png
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)
      })
    ]
  }
}

结果

文件打包结果
image.png

页面运行结果

image.png

webpack 运行结果

image.png
此上事例说明,DefinePlugin 只是替换模块内的字符串,可以用来在代码中判断环境。而不会改变webpack的环境变量。