推荐使用构建时注入环境变量(如.env.production中设react_app_api_base_url),由create react app在打包时内联到js中;需动态切换时,可用nginx sub_filter在返回html时注入window.__runtime_config__全局变量。

React 应用构建为静态文件后,通常用 Nginx 托管。但开发环境(如 http://localhost:3000)和生产环境(如 https://app.example.com)的 API 基础路径、资源前缀等常不同,硬编码会导致每次部署都要改代码。Nginx 本身不支持运行时 JS 变量替换,但可通过 构建时注入 + Nginx 变量配合 rewrite 或 header 传递 实现环境感知,真正实现“一份构建、多环境部署”。
构建时注入环境变量(推荐:使用 process.env + .env 文件)
React 官方脚手架(Create React App)支持在构建阶段读取 .env 文件中的变量,并注入到 process.env 中(仅限以 REACT_APP_ 开头的变量)。这是最安全、最标准的方式:
-
开发环境:创建
.env.development,写入REACT_APP_API_BASE_URL=http://localhost:8080/api -
生产环境:创建
.env.production,写入REACT_APP_API_BASE_URL=https://api.example.com/v1 - 在 JS 中直接使用:
fetch(process.env.REACT_APP_API_BASE_URL + '/users') - 执行
npm run build时,CRA 自动根据NODE_ENV选择对应 .env 文件,变量被内联进打包后的 JS,无需 Nginx 参与运行时逻辑
运行时动态配置(Nginx 配合 window.__RUNTIME_CONFIG__)
若需完全不重新构建就能切换后端地址(例如同一套 build 包用于测试/预发/正式),可让 Nginx 在返回 index.html 时注入全局 JS 变量:
- 在
index.html的中预留占位符:<script>window.__RUNTIME_CONFIG__ = {};</script> - Nginx 配置中使用
sub_filter替换该占位符(需启用ngx_http_sub_module):
location / {<br> root /var/www/my-react-app;<br> try_files $uri $uri/ /index.html;<br> sub_filter '<script>window.__RUNTIME_CONFIG__ = {};</script>' '<script>window.__RUNTIME_CONFIG__ = {API_BASE_URL: "https://api.prod.example.com/v1"};</script>';<br> sub_filter_once on;<br> sub_filter_types text/html;<br>}
- React 应用启动时读取:
const apiBase = window.__RUNTIME_CONFIG__.API_BASE_URL || '/api' - 注意:确保
sub_filter不被 gzip 干扰(可加gzip off;或用gzip_proxied no;控制)
利用 Nginx 变量控制静态资源路径(避免 CDN 路径硬编码)
当静态资源托管在 CDN(如 https://cdn.example.com)时,不想在代码里写死域名,可用 Nginx 的 proxy_set_header 或 add_header 传递上下文,再结合前端读取 document.currentScript 或 <base> 标签推导:
- 更简单可靠的做法:Nginx 返回 HTML 前,用
sub_filter注入<base href="/>%20%E6%88%96%E4%BF%AE%E6%94%B9%20public/%20%E4%B8%8B%E7%9A%84%20manifest.json%20%E5%BC%95%E7%94%A8%E8%B7%AF%E5%BE%84 %0A%20%20 - %E6%88%96%E7%BB%9F%E4%B8%80%E7%94%A8%E7%9B%B8%E5%AF%B9%E8%B7%AF%E5%BE%84%EF%BC%88%E5%A6%82%20
./static/js/main.abcd1234.js%EF%BC%89%EF%BC%8C%E7%94%B1%20Nginx%20%E7%9A%84%20root%20%E5%92%8C%20location%20%E8%A7%84%E5%88%99%E8%87%AA%E7%84%B6%E8%A7%A3%E6%9E%90%EF%BC%8C%E6%97%A0%E9%9C%80%E9%A2%9D%E5%A4%96%E5%8F%98%E9%87%8F %0A%20%20 - %E5%85%B3%E9%94%AE%E7%82%B9%EF%BC%9A%E7%A1%AE%E4%BF%9D%20
homepage%20%E5%AD%97%E6%AE%B5%E5%9C%A8%20package.json%20%E4%B8%AD%E8%AE%BE%E4%B8%BA%20" .>(相对路径)或 <code>""(根路径),避免 CRA 构建时添加错误前缀
避免常见陷阱
以下问题高频出现,直接影响环境切换是否生效:
-
不要在 JS 中直接读取
location.host判断环境:单页应用可能通过 hash 或 history 模式访问,host未必反映部署目标(如内网反向代理后 host 是localhost) -
禁止在 Nginx 中用
set $var+echo动态生成 JS:Nginx 变量无法跨请求保持,且echo模块非默认,易引发缓存和并发问题 -
确保
try_files正确 fallback:React Router 需要所有非资源路径都返回index.html,否则刷新 404;正确写法是try_files $uri $uri/ /index.html;,而非/index.html?/$request_uri - 区分构建时与运行时:95% 的场景用构建时注入(.env)足够;只有灰度发布、A/B 测试等特殊需求才引入运行时注入,复杂度和维护成本显著上升










