部署反应前端时如何注入 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 对于 developmentproduction 环境是常量,您可以使用 .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

如何部署 django 后端并将前端应用程序反应到同一域

Nginx部署前后端项目时的跨域问题

如何允许快速后端 REST API 在使用 axios 的反应前端中设置 cookie?

部署后反应路由器 url 问题

如何将后端(嵌套)文件中的 multer 图像放到我的前端(反应)上?