【问题标题】:How do I deploy a React app and a Rails API to Heroku?如何将 React 应用程序和 Rails API 部署到 Heroku?
【发布时间】:2017-07-28 05:10:47
【问题描述】:

我正在开发一个使用 React 作为客户端并使用 Rails API 作为服务器的应用程序。我想让客户端和服务器尽可能分开(现在它们位于完全不同的存储库中)。

React 客户端是使用 create-react-app 创建的,当前使用 package.json 文件中的代理选项调用 API,如下所示:

"proxy": "http://localhost:3001/"

Localhost 3001 是我的 Rails API 的位置。显然,这在生产中是行不通的。

如何在仍然让客户端访问服务器的同时将其部署到 Heroku?我可以部署两个不同的 Heroku 应用程序并以某种方式将客户端的应用程序代理请求发送到服务器的应用程序吗?还是我必须将客户端包含在我的 rails 项目中并一起部署?

【问题讨论】:

    标签: ruby-on-rails reactjs heroku deployment create-react-app


    【解决方案1】:

    我以前做过。我按照您在问题中的建议开始,构建了 react 应用程序并将其包含在我的 rails 项目中并部署了整个项目。这工作得很好,但我不想每次我想部署我的前端应用程序时都重新部署我的后端 API。

    所以我在我的 rails 应用程序中创建了一个名为 FrontEndAppVersion 的模型。我给这个模型两列:

    1. version - 您通常看到的语义版本字符串
    2. active - 一个布尔值,指示它是否是活动版本(一次只能激活一条记录)

    然后我有一个最小的 Rails 视图渲染,它将寻找活动的 FrontEndAppVersion 并链接到适当的 js 和 css 文件。

    在我的 react 应用程序中,我使用 gulp 打包应用程序并将其推送到云端,这是我的 rails 应用程序链接到的地方。除了将 react 文件发送到云端之外,我还让它向我的 rails 后端应用程序发出 api 请求,让它知道有一个新版本可用并使其成为活动版本。

    这可能有点矫枉过正,但它也让我可以轻松地回滚一个版本。除了回滚 Heroku,我可以通过创建不同的 FrontEndAppVersion 记录活动的应用程序来仅回滚客户端应用程序。

    无论您采用哪种方式,在您构建代理时都需要更改代理,如果两个应用位于同一域中,您只需使用 /

    【讨论】:

      【解决方案2】:

      在做同样的事情时,我采取了与 Jimmy 不同的方法。

      我在 Heroku 上部署了两个应用程序:一个 Rails API 和一个 Create-React-App 前端。无需太具体,有几个键可以设置它。首先,在您的 rails api 中,编辑 cors.rb 文件,使其允许跨域请求:

      Rails.application.config.middleware.insert_before 0, Rack::Cors do
        allow do
          origins 'localhost:3000', 'https://myapp.herokuapp.com'
      
          resource '*',
          headers: :any,
          methods: [:get, :post, :put, :delete],
        end
      end
      

      正如这个文件所暗示的,我的 rails 应用程序没有在本地运行 localhost:3000,我通过编辑 puma.rb 将其更改为在端口 8000 上运行:

      port        ENV.fetch("PORT") { 8000 }
      

      Create-react-app 默认在本地 localhost:3000 上运行,因此您可以将 rails api 设置为在您想要的任何端口上运行,只要它与您的前端不同。

      然后我在我的 create-react-app 中创建了一个文件,其中包含 API url 和我称之为 AppConstants.js 的常用端点:

      // let APIRoot = "http://localhost:8000";
      let APIRoot = "https://my-rails-api.herokuapp.com";
      
      export default {
        APIEndpoints: {
          LOGIN:  APIRoot + "/users/login",
          SIGNUP: APIRoot + "/users/create",
          TODOS: APIRoot + "/todos",
          ITEMS: APIRoot + "/items",
        },
      };
      

      现在您编辑您的 fetch/ajax/xmlHttpRequest 调用,以便它使用的 URL 引用这些路由。例如使用 fetch:

      fetch(AppConstants.TODOS, {
        method: 'POST',
        body: JSON.stringify(values)
      })
      .then(response => response.text())
      .then((body) => {
        console.log(body);
      });
      

      此应用程序常量文件可以轻松地在本地 api 根目录和生产 api 根目录之间切换。

      像往常一样将您的 rails api 部署到 heroku,将自动检测到合适的构建包。对于您的 React 应用程序,我建议使用 this buildpack 来构建您的 create-react-app 的生产版本并为您提供静态资产。

      【讨论】:

      • 恕我直言,这应该是公认的答案。这是在架构上设置两个涵盖不同关注点的独立应用程序的最佳方式,imo。
      猜你喜欢
      • 2020-05-08
      • 2015-12-25
      • 2018-03-31
      • 2020-09-02
      • 1970-01-01
      • 2020-07-09
      • 1970-01-01
      • 1970-01-01
      • 2018-08-05
      相关资源
      最近更新 更多