关于webpack:Webpack配置环境变量

45次阅读

共计 3862 个字符,预计需要花费 10 分钟才能阅读完成。

在理论我的项目开发中,须要基于多种环境去设置不同的环境变量以便于在构建阶段或是运行阶段去应用,例如常见的通过 process.env.NODE_ENV 在构建时去判断以后的构建环境是 development 还是 production,例如须要在 开发环境 测试环境 生产环境 去拜访不同的接口服务器。

为了模仿实在的我的项目,应用 webpack 搭建了一个最小化的我的项目构造:

├─package.json
├─src
|  └index.jsx
├─public
|   └index.html
├─config
|   └webpack.config.js

Node 环境变量

Node 环境变量就是指 process.env 这个属性

process.env 是什么?

它是 Nodejs 应用程序中,process.env 属性,返回蕴含用户环境的对象,所以它不能够在客户端侧代码中应用,也就不能在浏览器环境上应用。

// process.env(官网示例)
{
  TERM: 'xterm-256color',
  SHELL: '/usr/local/bin/bash',
  USER: 'nodejscn',
  PATH: '~/.bin/:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin',
  PWD: '/Users/nodejscn',
  EDITOR: 'vim',
  SHLVL: '1',
  HOME: '/Users/nodejscn',
  LOGNAME: 'nodejscn',
  _: '/usr/local/bin/node'
}

批改 Node 环境变量

1. 批改 package.json 文件

应用 cross-env依赖包,反对跨平台配置环境变量。

// package.json
{
  ...,
  "scripts": {
    "start": "npm run dev",
    "dev": "cross-env NODE_ENV=development AAA=123 webpack serve --config ./config/webpack.config.js",
    "build:test": "cross-env NODE_ENV=test  webpack --config ./config/webpack.config.js",
    "build:pro": "cross-env NODE_ENV=production  webpack --config ./config/webpack.config.js"
  },
  ...
}

通过在 package.json 脚本中设置变量的形式来注入环境变量,同时 cross-env 还反对去设置多个环境变量,只须要通过空格辨别,例如在 dev 脚本中设置的 NODE_ENV=developmentAAA=123

这样在执行 npm start 就可能通过 process.env 获取到对应的环境变量。

// webpack.config.js
console.log("【process.env】", process.env.AAA);

可能在构建时的终端中打印出

然而在 index.jsx 中也就是浏览器环境下的文件中打印 process.env 就会报错

起因就是前文提到的 peocess.env 是 Node 环境的属性,浏览器环境不可能获取到。让浏览器环境获取到所需变量咱们后文再说。

2. 通过.env 文件注入

间接通过在 script 脚本中注入环境变量的形式不利于集中管理环境变量,而且在环境变量较多时这种形式也非常不敌对,所以须要一种形式来集中管理这些环境变量。

应用 dotenv 依赖包可将环境变量从 .env 文件加载到 process.env

dotenv会默认加载根目录的 .env 文件去注入环境变量,通过 require('dotenv').config() 即可实现注入。

//webpack.config.js
dotenv.config();

//.env 文件
AAA=123

同样也可能在终端中看到

dotenv 多环境配置

在多环境配置时须要通过规定不同环境对应的 .env 文件,例如当初规定 .env.test 是测试环境对应的环境变量,.env.production是生产环境,.env是开发环境。而后通过 dotenv.config({path:}) 去加载对应文件的环境变量。

//webpack.config.js
const PROJECT_PATH = resolve(__dirname, "../");

const dotenvFile = resolve(PROJECT_PATH, `./.env.${process.env.NODE_ENV}`);

// 加载.env* 文件  默认加载.env 文件
dotenv.config({path: fs.existsSync(dotenvFile)
    ? dotenvFile
    : resolve(PROJECT_PATH, `./.env`),
});

console.log("【process.env】", process.env.ENV);

这里 process.env.NODE_ENV 是为了判断以后的运行环境来去加载对应的 .env 文件。

// package.json
"scripts": {
  "start": "npm run dev",
  "dev": "cross-env NODE_ENV=development webpack serve --config ./config/webpack.config.js",
  "build:test": "cross-env NODE_ENV=test  webpack --config ./config/webpack.config.js",
  "build:pro": "cross-env NODE_ENV=production  webpack --config ./config/webpack.config.js"
}

//.env.production
ENV=pro

//.env
ENV=dev

执行npm start

执行npm run build:pro

能够看到不同环境的变量的确曾经注入胜利。

浏览器环境变量

浏览器环境下也须要依据不同的环境变量来解决一些逻辑,然而它不能获取到 process.env 所以不能像注入 Node 环境变量的形式来实现。浏览器环境变量是基于 webpack.DefinePlugin 这个插件在我的项目构建时引入的,引入之后能够在前端代码中全局获取到对应的变量。

根底应用形式是将所需的变量按键值对的形式传入 DefinePlugin 中,须要留神的是变量值须要通过 JSON.stringify 进行包裹。

module.exports = {
  plugins: [
    new DefinePlugin({aaa: JSON.stringify("!!!!")
    })
  ]
}

执行脚本后能够在 index.jsx 中失去对应的后果

//index.jsx
console.log("【app】", aaa);
const App = () => {return <div>app</div>;};

配置多环境的浏览器变量

浏览器环境中也须要依据我的项目环境来引入不同的变量,之前在 Node 环境中曾经获取到不同的环境变量,咱们能够建设一个基于此的映射表在我的项目构建时依据拿到的 Node 环境变量来引入对应的浏览器环境变量。

// webpack.config.js

// 浏览器环境注入的变量
const define = {
  dev: {baseURL: "/api/dev",},
  test: {baseURL: "/api/test",},
  pro: {baseURL: "/api/pro",},
};

module.exports = {
  new DefinePlugin({"process.env": Object.keys(define[process.env.ENV]).reduce((env, key) => {env[key] = JSON.stringify(define[process.env.ENV][key]);
      return env;
    }, {}),
  }),
}

执行npm start,能够在浏览器控制台看到后果

执行npm run build:pro,在 dist 目录开启一个服务器,能够在浏览器控制台看到后果

在理论我的项目中依据不同环境切换接口服务器地址的场景中,就能通过这样的形式来获取到不同环境中的接口地址。

在 UMI 中去配置多环境变量

在平时开发中较常应用 umi 作为我的项目框架,umi通过环境变量 UMI_ENV 辨别不同环境来指定不同配置。

具体来说是通过脚本中注入的 UMI_ENV=xxx 去匹配对应的 config.xxx.js 配置文件,而后在 define 属性中去配置须要引入浏览器环境的变量。

具体相干内容能够看官网文档多环境配置,
代码中可用的变量

// webpack.config.js
module.exports = {
  ...,
  "scripts": {
    "start": "cross-env UMI_ENV=dev umi dev",
    "build:test": "cross-env UMI_ENV=test umi build",
    "build:pre": "cross-env UMI_ENV=pre umi build",
    "build:pro": "cross-env UMI_ENV=pro umi build",
  }
  ...,
}

//config.dev.js
import {defineConfig} from 'umi';

export default defineConfig({
  define: {
    'process.env': {BASE_API: '/api/dev',},
  },
});

正文完
 0