React 添加环境变量

6,831 阅读2分钟

通常情况下,开发环境和线上环境用的 API 的 URL 不是同一个,所以并不能将 URL 写死,而是要根据不同的环境,使用不同的 API.

内置环境

create-react-app 创建的项目有内置的环境变量 NODE_ENV, 在 JavaScript 代码中可通过 process.env.NODE_ENV 读取它。

NODE_ENV 默认有三个可能的值,分别是 development, testproduction, 对应开发,测试,生产环境。

运行 npm start, NODE_ENV 的值为 development; npm run test 则是 test; npm run build 则对应 prodution.

比如开发环境的 API 的 URL 为 urlDev, 生产环境的 URL 为 urlProd, 就可通过环境变量,判断当前环境,使用相应的 URL:

let env = process.env.NODE_ENV

let baseUrl = ''

if (env === 'development') {
  baseUrl = urlDev
} else if (env === 'production') {
  baseUrl = urlProd
}

get(baseUrl) // 伪代码,表示请求动作
...

一般来说,这三个值够用了。

但是需要更多环境的话呢,比如,需要一个开发环境,一个测试环境,一个 UAT (User Acceptance Testing) 环境,一个 stage 环境,一个 production 环境。

掰掰手指数一数,发现上面三兄弟不够用了。

这个时候需要自定义环境变量。

多环境

分析

求助于文档,给了两个方法:

  1. shell 环境添加,写在命令行,类似运行下面这样的命令
  set "REACT_APP_SECRET_CODE=abcdef" && npm start

但是这种方式只是在 Shell 中添加临时的变量,JavaScript 是读取不到的。

  1. .env 文件添加,即在项目的根目录添加一个名为 .env的文件,在里面添加环境变量,这样的变量在 JavaScript 是可以读取到的。

    还有不同的文件名可在不同的环境进行覆盖,比如将文件命名为 .env.development, 在开发环境即可读取文件内定义的变量。同样,.env.test.env.production 分别对应测试环境和生产环境。

    这种方式,显而易见,只支持内置的三个环境。

文档里面还透漏一个重要信息,react 只读取 REACT_APP 开头的变量,其他的,表示不认识。

比如简单写个 MY_ENV, 是会被 React 忽略的,而 REACT_APP_ENV 就会被读取。

配置

有个思路,就是从命令行入手,然后搞一个 JavaScript 可以读到的永久环境变量。

这里需要 cross-env, cross-env 设计是为了定义全平台兼容的环境变量命令,因为 Windows 在设置环境变量的命令会出现阻塞问题。

首先安装 cross-env:

npm install --save-dev cross-env

然后在 package.jsonscripts 里面添加代码。

比如我要设置 stage 环境下的环境变量 REACT_APP_ENVstage, 只需在 package.json 添加如下代码

"build:stage": "cross-env REACT_APP_ENV=stage react-scripts build"

其中 cross-env REACT_APP_ENV=stage 定义了 REACT_APP_ENVstage.

然后得到:

"scripts": {
	"start": "react-scripts start",
    "build": "react-scripts build",
    "build:stage": "cross-env REACT_APP_ENV=stage react-scripts build",
	"test": "react-scripts test",
	"eject": "react-scripts eject"
}

这样一来,运行 npm run build:stage 打包之后,process.env.REACT_APP_ENV 的值即为 'stage'.

其他要添加什么环境,以此类推。