部署反应前端时如何注入 API 服务器 URL?
Posted
技术标签:
【中文标题】部署反应前端时如何注入 API 服务器 URL?【英文标题】:How to inject API server URL when deploying react frontend? 【发布时间】:2018-12-04 02:12:52 【问题描述】:免责声明:我是 React 菜鸟,所以也许我想要做的不是 React 方式
我正在编写一个 React 前端,它将被部署以由某些云提供商静态提供服务,例如S3 或谷歌存储或其他任何东西。此前端与位于云中某处的多个 API 服务器交互,可能在同一个提供商中,也可能不在。此外,在开发 UI 或其一部分时,这些服务器的地址可能是本地或测试实例。
如何灵活地将 API 服务器 URL 注入到我的 react 应用程序中,以便我可以使用不同的地址在 dev、staging 或 prod 中进行部署?
解决方案:我最终使用了建议的解决方案组合:
使用.env.production
和.env.development
文件(确切名称)来存储变量REACT_APP_API_URI = 'host'
这是由 create-react-app 的构建脚手架自动获取的,并在 UI 代码中作为 process.env.REACT_APP_API_URI
提供
请注意,这有点违背 12 Factor Apps 的原则,例如在版本控制中将环境变量存储在文件中,但它可以完成 ATM 的工作。
【问题讨论】:
我通常将.env.sample
添加到 repo 而不是带有值的实际文件。此外,您还可以在 CI/CD 中设置该环境变量,以更好地与 12 Factor 方法保持一致。
不错的解决方案。将.env.production
和.env.development
文件添加到根目录后,您可以使用console.log(process.env.NODE_ENV)
和console.log(process.env.REACT_APP_API_URI)
从任何地方观看。
重要提示:使用create-react-app
,您需要在变量名前加上REACT_APP_
前缀才能访问它。
【参考方案1】:
你可以试试这个:
switch(process.env.NODE_ENV)
case 'production':
url = 'https://***.com';
break;
case 'development':
default:
url = 'https://google.com';
【讨论】:
你可以在这里看到例子github.com/gianglevan94/auto-shop/blob/master/resources/assets/… 但是process.env.NODE_ENV
假设有一个节点服务器正在运行,不是吗?这意味着这在运行时有效,而不是在构建时。
所以你的意思是 webpack 会自省 JS 代码并用它们的值静态替换这些变量?
是的。我打赌你使用 create-react-app。当您将其部署为生产时,您将构建捆绑包,并且 NODE_ENV 将设置为“生产”并且您的 api url 将是 ***.com 而不是 google.com【参考方案2】:
使用这个包 https://github.com/toddbluhm/env-cmd 你可以为你的环境创建一个 env 文件
例如使用此代码创建 .env.staging 和 .env 文件
// .env.staging file
API_URL=https://staging.url.com/api/
// .env file
API_URL=https://url.com/api/
如何使用 API_URL 从环境变量中获取:
fetch(process.env.API_URL)
然后你可以在你的 package.json 中添加一些额外的脚本:
"scripts":
"build:staging": "env-cmd .env.staging yarn build",
"build:prod": "env-cmd .env yarn build"
【讨论】:
但是.env
文件是在运行时读取的? process.env.API_URL
变量是什么时候定义的?我希望在构建/部署时发生这种情况,以便当应用程序在浏览器中执行时,它会使用正确的 URL 进行静态配置。
不,当您运行包含它的命令时,它将转换 process.env.API_URL
。例如,如果您运行命令yarn build:staging
来构建react,它会将fetch(process.env.API_URL)
转换为fetch('https://staging.url.com/api/')
,然后您可以将构建文件部署到登台服务器。【参考方案3】:
如果 API 对于 development
或 production
环境是常量,您可以使用 .env
文件。在build
之后,您无法更改这些参数。
如果您想在构建后更改URL
,请添加一个js
文件让我们说config.js
在index.html
中包含conf.js
在conf.js
中添加URL
喜欢
var URL1 = 'https://www.google.com'
你可以像这样访问参数:
export const URL1 = window;
【讨论】:
但是如果我们这样做,那么 URL1 将是公开的。任何人都可以看到它。 是的,这不是一个好习惯。必须有一个托管 reactjs 应用程序的后端服务器。这样您就可以使用路由名称访问服务器,而不是使用 ip 和端口,IP、端口将与 reactjs 应用程序相同。然后,您可以从服务器端从所需的应用程序中获取数据。【参考方案4】:例如,您可以在构建步骤中使用环境变量来做到这一点。
您可以使用类似.env 的东西,例如,它允许您定义环境变量并将它们加载到您的 webpack 文件中(假设您使用 webpack)。但你真的可以将它与任何捆绑器一起使用。
.env 文件:
API=http://localhost:3000
在您的 webpack 上,您可以使用 DefinePlugin
来自文档的示例:添加您的 API 环境
...
require('dotenv').config()
...
new webpack.DefinePlugin(
API_ENDPOINT: process.env.API,
PRODUCTION: JSON.stringify(true),
VERSION: JSON.stringify('5fa3b9'),
BROWSER_SUPPORTS_HTML5: true,
TWO: '1+1',
'typeof window': JSON.stringify('object')
);
无论如何,这只是一种方式。我喜欢这种方式,因为它使我的项目可以为不同的环境定义 API 密钥和其他有用的东西。
注意:您甚至可以为本地、暂存和生产定义不同的 .env 文件,并根据构建类型将各自的文件加载到 webpack 中。
【讨论】:
这是有道理的,但我已经使用create-react-app
来搭建我的应用程序,而它似乎 无法使用 webpack。还是在引擎盖下使用它?
@insitu 是的,它确实在后台使用了 webpack。它使用反应脚本。
@insitu 看看这个帖子:medium.com/@tacomanator/… 这基本上是我的方法并使用 CRA
这令人困惑:process.env.XXX
在构建时可用吗?以上是关于部署反应前端时如何注入 API 服务器 URL?的主要内容,如果未能解决你的问题,请参考以下文章
部署单独的 React 前端和 Django DRF API