如何将项目根目录的.env文件配置读取到React客户端应用中
问题根源
react-scripts(客户端使用的启动工具)原生不支持运行时动态读取.env文件,所有环境变量是在启动/打包阶段就静态注入到前端代码中的,在前端代码里手动引入dotenv读文件本身无效,也拿不到运行时的路径。- 你编写的shell脚本失效是因为
grep | while read的结构会创建子shell,循环内export的变量仅在子shell生效,执行npm run dev的父进程拿不到这些变量,所以React里读不到。 - 你遇到的process.cwd()指向根目录的问题,大概率是本地Node环境或终端配置异常,正常情况下在哪个目录执行命令,cwd就是对应目录。
可直接落地的解决方案
不用修改现有目录结构,就能实现服务端和客户端共用根目录.env,这里提供两种通用实现:
方案1:使用dotenv-cli加载指定env文件(操作最简,无需写shell脚本)
- 先在项目根目录安装dotenv-cli作为开发依赖:
npm install dotenv-cli --save-dev
- 修改根目录package.json的
dev命令,给客户端启动前指定加载根目录的.env文件:
"dev": "concurrently \"npm run start-watch\" \"cd client && dotenv -e ../.env react-scripts start\""
- 注意规则:根目录.env里需要给前端使用的变量必须加
REACT_APP_前缀,比如后端接口地址要给前端用,就写为REACT_APP_API_URL=http://localhost:3001,前端直接通过process.env.REACT_APP_API_URL就能读取,不需要自己编写任何dotenv加载逻辑。
方案2:修复原有shell脚本
如果不想额外安装依赖,将你的shell脚本修改为如下内容即可解决子shell导出变量失效的问题:
#!/bin/sh # 直接在当前shell加载.env的所有变量,自动添加REACT_APP_前缀 while IFS= read -r line || [ -n "$line" ]; do # 跳过注释和空行 case "$line" in \#*) continue ;; '') continue ;; esac key=$(echo "$line" | cut -d '=' -f 1) value=$(echo "$line" | cut -d '=' -f 2-) export "REACT_APP_$key=$value" done < .env # 启动项目 npm run dev
执行脚本前需要先给脚本加执行权限:chmod +x 你的脚本名称.sh,之后直接运行脚本启动项目即可。
常见问题排查
如果还是出现客户端读不到.env的情况,优先排查两个高频问题:
- 如果你在client目录下也存放了.env文件,
react-scripts会默认优先加载client目录下的.env,需要删除或者改名 - 每次修改.env文件后,必须重启整个dev服务才能生效,变量不支持热更新
内容的提问来源于stack exchange,提问作者H Ferguson
相关产品推荐
相关产品推荐

