React应用经Gitlab Kubernetes部署后env未定义,如何像Next.js一样使用环境变量

该应用通过Gitlab Kubernetes完成部署,部署完成后读取环境变量返回undefined。

React项目实现类Next.js环境变量方案
Next.js的环境变量核心逻辑为两点:一是通过前缀区分服务端/客户端可用变量,避免敏感变量泄露到前端;二是支持运行时注入变量,无需重新打包即可更新配置。React项目可按以下两种方案实现同等能力:
方案1:基于Create React App默认规则实现基础版
Create React App(CRA)脚手架默认自带和Next.js类似的前缀隔离规则:
- 不带
REACT_APP_前缀的变量:仅能在构建脚本、Node.js侧代码中读取,不会打包进入前端客户端产物,避免泄露 - 带
REACT_APP_前缀的变量:构建时会自动注入到前端代码中,可直接通过process.env.REACT_APP_XXX在业务代码中读取
注意:默认CRA的环境变量为构建时注入,变量值会硬编码到打包后的静态文件中,部署到Kubernetes时再传入环境变量无法生效,这就是部署后读取返回undefined的核心原因。
方案2:实现运行时环境变量注入(适配K8s部署场景)
如果需要实现和Next.js一致的运行时动态修改变量能力,无需每次更换环境重新打包,按以下步骤操作:
步骤1:创建环境变量模板
在public目录下新建env.template.js文件,定义需要运行时注入的变量占位符:
window.RUNTIME_ENV = { API_BASE_URL: '__REACT_APP_API_BASE_URL__', APP_ENV: '__REACT_APP_APP_ENV__' // 其余需要动态注入的变量按同样格式添加 }
步骤2:引入环境变量文件
在public/index.html的<head>标签最顶部引入该文件:
<script src="%PUBLIC_URL%/env.js"></script>
步骤3:编写变量替换脚本
在项目根目录新建inject-env.sh脚本,用于启动服务前替换占位符为实际环境变量:
#!/bin/bash # 复制模板文件到打包产物目录 cp public/env.template.js build/env.js # 遍历所有REACT_APP_开头的环境变量,替换对应占位符 for env_item in $(printenv | grep REACT_APP_); do key=$(echo "$env_item" | cut -d'=' -f1) value=$(echo "$env_item" | cut -d'=' -f2) sed -i "s|__${key}__|${value}|g" build/env.js done
执行以下命令给脚本添加执行权限:chmod +x inject-env.sh
步骤4:修改K8s启动命令
在Gitlab CI配置或K8s Deployment的启动命令中,先执行替换脚本再启动静态资源服务,以Nginx为例:
/bin/sh inject-env.sh && nginx -g 'daemon off;'
步骤5:封装统一读取工具
在业务代码中封装统一的环境变量读取方法,抹平构建时和运行时变量的差异:
// src/utils/env.js export const getEnv = (key) => { return window.RUNTIME_ENV?.[`REACT_APP_${key}`] || process.env[`REACT_APP_${key}`] } // 业务代码调用示例 const apiBaseUrl = getEnv('API_BASE_URL')
内容的提问来源于stack exchange,提问作者Shafayet
相关产品推荐
相关产品推荐

