多环境场景下React应用部署至Amazon S3存储桶的接口配置方案
S3部署React应用多环境配置可行方案
首先明确根本逻辑:process.env是Node.js运行时的变量,React项目打包后为纯静态文件,运行在浏览器环境中不存在原生process.env对象,你代码中能读到的process.env值都是构建阶段静态替换的常量,和S3是否支持环境变量无关。以下是三种可直接落地的方案:
方案1:构建阶段注入环境变量(最常用)
在打包不同环境的静态资源时,传入对应环境标识,构建工具会直接把变量值替换到打包后的JS文件中,不同环境的构建产物分别上传到对应S3桶即可,代码完全不需要硬编码区分,不会产生Git冲突。
以Create React App(CRA)为例:
- 环境变量必须以
REACT_APP_为前缀,修改原有逻辑:
// index.js let BASE_API_URL; if (process.env.REACT_APP_ENV === "production") { BASE_API_URL = "https://myproductionapiurl.com"; } else if (process.env.REACT_APP_ENV === "staging") { BASE_API_URL = "https://mystagingapiurl.s3-website.us-east-2.amazonaws.com"; } else { BASE_API_URL = "https://someotherurl.com"; } axios.defaults.baseURL = BASE_API_URL;
- 在
package.json中新增对应环境的构建脚本:
{ "scripts": { "build:staging": "REACT_APP_ENV=staging react-scripts build", "build:prod": "REACT_APP_ENV=production react-scripts build" } }
- 打包staging环境资源时执行
npm run build:staging,产物上传staging S3桶;打包生产环境资源时执行npm run build:prod,产物上传生产S3桶即可。
如果使用Vite,只需要把变量前缀改为VITE_,构建命令对应调整即可。
方案2:根据前端访问域名动态判断
因为你的staging和生产环境的前端访问域名不同,不需要依赖任何环境变量,直接通过浏览器全局对象window.location.host判断当前环境即可,同一份代码可以直接上传到任意环境的S3桶,不需要多套构建流程。
示例代码:
// index.js const currentHost = window.location.host let BASE_API_URL; if (currentHost === "你的生产前端域名,比如www.xxx.com") { BASE_API_URL = "https://myproductionapiurl.com"; } else if (currentHost === "你的staging前端域名,比如staging.xxx.com") { BASE_API_URL = "https://mystagingapiurl.s3-website.us-east-2.amazonaws.com"; } else { BASE_API_URL = "https://someotherurl.com"; } axios.defaults.baseURL = BASE_API_URL;
方案3:独立配置文件托管
把环境配置和业务代码完全分离,每个S3桶根目录存放一个独立的config.json配置文件,前端启动时先拉取当前桶的配置文件再初始化接口请求,后续修改配置不需要重新打包代码,直接修改S3中的config.json即可。
操作步骤:
- 在staging S3桶根目录新建
config.json,内容为:
{ "BASE_API_URL": "https://mystagingapiurl.s3-website.us-east-2.amazonaws.com" }
- 在生产S3桶根目录新建
config.json,内容为:
{ "BASE_API_URL": "https://myproductionapiurl.com" }
- 修改前端初始化逻辑,先拉配置再渲染应用:
// index.js fetch('/config.json') .then(res => res.json()) .then(config => { axios.defaults.baseURL = config.BASE_API_URL // 原有的React根组件渲染逻辑放在这里 ReactDOM.createRoot(document.getElementById('root')).render(<App />) })
内容的提问来源于stack exchange,提问作者Jorche
相关产品推荐
相关产品推荐

