二、React环境变量

官网文档地址:https://www.html.cn/create-react-app/docs/adding-custom-environment-variables/
dotenv配置与使用:https://juejin.cn/post/6917794798732574733
dotenv 的使用:https://juejin.cn/post/6844904198929121288

仅供自己学习使用,喷子勿评。
npm -g install dotenv-cli

在实际开发中,前端er会面对多个环境的接口:开发环境、测试环境、生产环境...这些环境最终要的区别是API的URL不同,所以代码中不能将URL写死,而是要根据不同的环境配置。

注:create-react-app或者 umi这样的脚手架初始化的项目,会将webpack的配置黑盒化了,如何在不执行 eject 操作的前提下优雅地配置多个项目环境呢?(最好不要一遇到问题就一键执行 eject 操作, eject 操作是不可逆的,执行之后会把所有细节都暴露在我们面前,让项目目录变得很庞大)

create-react-app 支持多环境,接下来我们一起看下如何设置。

1、react自带的两个环境变量:

1.1)NODE_ENV

create-react-app 创建的项目有内置的环境变量NODE_ENV,该变量是自动赋值的,不可更改。在js代码中可通过 process.env.NODE_ENV 读取它。NODE_ENV 默认有三个可能的值,分别是:

  1. development:开发环境,运行 npm start, NODE_ENV 的值为 development;
  2. test:测试环境,运行npm run test 则是 test;
  3. production:生产环境,运行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) // 伪代码,表示请求动作

简单的系统,我们通过上面代码已经能够完成不同环境的设置了。

1.2)PUBLIC_URL:

这个变量可以用于引用模块系统之外的资源路径前缀,用create-react-app脚手架创建的react项目,在public目录下,有index.html、favicon.ico等文件,index.html中使用了该变量引用图片:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />

默认改变量的值是空(“”),上面index.html中,href=“/favicon.ico”表示站点根路径,可以设置该变量为cdn,加速静态资源访问效率。

1)如何使用改变量:

html中通过%PUBLIC_URL% 获取变量值
js中通过process.env.PUBLIC_URL 获取变量值

2)设置该变量:

在.env文件中设置该变量的值为一个合法的url路径,打包后,在使用该变量的文件中就会被替换成对应的值。(.env文件相关内容见下文)

更多的自建变量:https://create-react-app.dev/docs/advanced-configuration/

2、多环境设置:

项目的根目录添加一系列名为 .env的文件,里面写上变量名和值,打包后,可以在js代码中通过process.env.REACT_APP_XXX读取到对应文件中的变量值。
注:文件中的变量必须以REACT_APP_ 开头,其他的react不识别。
说明:此功能适用于 react-scripts@0.5.0 及更高版本,可以通过以下命令更新:

npm install --save --save-exact react-scripts@1.1.4
2.1)默认可以使用哪些 .env 文件?

默认,可以在项目根目录下建立如下文件:

  • .env:默认。
  • .env.local:本地覆盖。除 test 之外的所有环境都加载此文件。
  • .env.development, .env.test, .env.production:设置特定环境。
  • .env.development.local, .env.test.local, .env.production.local:设置特定环境的本地覆盖。

左侧的文件比右侧的文件具有更高的优先级:

  • npm start: .env.development.local, .env.development, .env.local, .env
  • npm run build: .env.production.local, .env.production, .env.local, .env
  • npm test: .env.test.local, .env.test, .env (注意没有 .env.local )

注:实际测试发现添加完.env文件后,需要重新执行npm start后,代码中获取变量才能生效。

看个示例:

1)在项目根目录建立两个文件:

.env.development文件,内容:REACT_APP_TEST=development
.env.production文件,内容:REACT_APP_TEST=production

2)在js中通过如下代码访问变量:
function App() {
  return (
    <div className="App">
      {process.env.REACT_APP_TEST}<br/>
    </div>
  );
}
export default App;
3)访问变量值:

执行npm start后,访问页面,得到的变量值为:development
执行npm build后,再执行serve -s build,访问页面,得到的变量值为:production

2.2)dotenv管理环境变量:

上面知道,默认通过create-react-app创建的react项目只能支持上面几种.evn文件,并且通过npm run build只能指定.env.production和默认.env文件中的环境变量,假设系统还有个stage环境,该如何指定呢?官方推荐使用dotenv来做环境变量的管理。dotenv的github地址:https://github.com/motdotla/dotenv

看一个例子:

1)在项目根目录建立三个文件:
  • .env.development文件,内容:REACT_APP_TEST=development
    .env.stage文件,内容:REACT_APP_TEST=stage
    .env.production文件,内容:REACT_APP_TEST=production
2)在js中通过如下代码访问变量:

同上

3)修改 package.json 中的 scripts来指定环境:
 "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "build:stage": "dotenv -e .env.stage react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
4)访问变量值:

npm run build:stage

在使用前需要安装dotenv-cli(https://github.com/entropitor/dotenv-cli),否则会报如下错误:

# npm run build:stage
 
> test@0.1.0 build:stage /tmp/test
> dotenv -e .env.development react-scripts build
 
sh: dotenv: command not found
npm ERR! file sh
npm ERR! code ELIFECYCLE
npm ERR! errno ENOENT
npm ERR! syscall spawn
npm ERR! test@0.1.0 build:stage: `dotenv -e .env.development react-scripts build`
npm ERR! spawn ENOENT
npm ERR! 
npm ERR! Failed at the test@0.1.0 build:stage script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
 
npm ERR! A complete log of this run can be found in:
npm ERR!     /root/.npm/_logs/2020-08-30T16_22_57_811Z-debug.log

安装dotenv-cli:

# npm -g install dotenv-cli
[..................] / rollbackFailedOptional: verb npm-session dfed37ae051d8c52
[..................] \ fetchMetadata: sill resolveWithNewModule dotenv-cli@3.2.0 checking installable status
[..................] \ fetchMetadata: sill resolveWithNewModule dotenv-cli@3.2.0 checking installable status
/usr/local/node-v12.9.0-linux-x64/bin/dotenv -> /usr/local/node-v12.9.0-linux-x64/lib/node_modules/dotenv-cli/cli.js

然后再次执行:npm run build:stage,之后启动serve:serve -s build
访问页面,得到变量值为:test

参考:

https://www.html.cn/create-react-app/docs/adding-custom-environment-variables/

https://juejin.im/post/6844904015528984583

https://blog.csdn.net/ZYC88888/article/details/82729313

https://juejin.im/post/6844903968288538638
————————————————
原文链接:https://blog.csdn.net/liuxiao723846/article/details/108313832

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容