简体   繁体   English

在Heroku上使用Rails API部署Create-React-App

[英]Deploying Create-React-App with Rails API on Heroku

I'm having an issue getting my react /rails app to work on heroku. 我在使我的react / rails应用程序在heroku上工作时遇到问题。 I've managed to get it deployed and the rails server starts but I'm not seeing my react app. 我设法部署了它,并且启动了Rails服务器,但是我没有看到我的react应用程序。 I feel like I'm close but can't figure out what's missing. 我觉得我已经接近了,但无法弄清缺少的东西。

So my process is currently to run npm run build locally from the client directory which builds a 'build' directory in client. 因此,我目前的流程是从客户端目录本地运行npm run build ,这会在客户端中构建“ build”目录。 I then commit the results of the build and push to Heroku with git push heroku master . 然后,我提交构建结果,并使用git push heroku master推送到Heroku。

I then navigate to the heroku app in a browser where I'm only getting a blank white page which is an index file the I manually copied from the build dir to public. 然后,我在浏览器中导航到heroku应用程序,在该浏览器中我只得到一个空白的白页,这是我从构建目录手动复制到公共目录的索引文件。 I'm not sure if the index file is correct but I just wanted to make sure i could hit something. 我不确定索引文件是否正确,但我只是想确保可以打到一些东西。

Ultimately, I would like to just push the repo and it automatically run the build. 最终,我只想推送仓库,它会自动运行构建。 I've seen this mentioned various places but I always get a react-script does not exist error when I run npm run build on the server. 我已经看过这里提到过的各个地方,但是当我在服务器上运行npm run build时,总是收到一个react-script不存在的错误。

My configuration is as follows: 我的配置如下:

basic structure of app 应用程序的基本结构

/app - root of Rails app
/client - root of React app
/public - does display index page

root/client/package.json 根/客户机/的package.json

{
    "name": "qc_react",
    "version": "0.1.0",
    "private": true,
    "devDependencies": {
        "react-scripts": "^0.8.4"
    },
    "dependencies": {
        "react": "^15.4.1",
        "react-dom": "^15.4.1",
        "react-router": "^3.0.0"
    },
    "scripts": {
        "start": "react-scripts start",
        "build": "react-scripts build",
        "test": "react-scripts test --env=jsdom",
        "eject": "react-scripts eject"
    },
    "cacheDirectories": [
        "node_modules",
        "client/node_modules"
    ],
    "proxy": "${API_URL}:${PORT}/v1/"
}

root/package.json 根/的package.json

{
  "name": "web",
  "version": "1.0.0",
  "description": "This repo contains a web application codebase. Read instructions on how to install.",
  "main": "index.js",
  "scripts": {
    "build": "cd client" # not sure what to put here but this gets me past build failure
  },
  "repository": {
    "type": "git",
    "url": "git+ssh://myrepo.git"
  },
  "author": "",
  "license": "ISC",
  "homepage": "https://myhomepage#readme"
}

Procfile Procfile

api: bundle exec puma -C config/puma.rb

Buildpacks Buildpacks

1. https://github.com/mars/create-react-app-buildpack.git
2. heroku/ruby

config/puma.rb 配置/ puma.rb

workers Integer(ENV['WEB_CONCURRENCY'] || 2)
threads_count = Integer(ENV['RAILS_MAX_THREADS'] || 5)
threads threads_count, threads_count

preload_app!

rackup      DefaultRackup
port        ENV['PORT']     || 3001
environment ENV['RACK_ENV'] || 'development'

on_worker_boot do
  # Worker specific setup for Rails 4.1+
  # See: https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server#on-worker-boot
  ActiveRecord::Base.establish_connection
end

That's because Rails is serving static files (including index.html ) from /public . 这是因为Rails正在从/public提供静态文件(包括index.html )。 But your React app bundle is located inside /client/build . 但是您的React应用程序包位于/client/build After build you need to copy these files back to Rails folder. 构建后,您需要将这些文件复制回Rails文件夹。 The easiest way to do this is to add some scripts to your package.json : 最简单的方法是在package.json添加一些脚本:

"scripts": {
  ...
  "deploy": "cp -a build/. public",
  "heroku-postbuild": "npm run build && npm run deploy"
},

heroku-postbuild is executed automatically by Heroku after all dependencies are installed, just like normal postinstall hook. 在安装所有依赖项之后, heroku-postbuild由Heroku自动执行,就像普通的postinstall挂钩一样。

Be careful with the paths for cp command. 小心cp命令的路径。 Your setup with 2 different package.json files is too complex. 您使用2个不同的package.json文件进行的设置太复杂了。 I recommend to use a single package.json inside root and set all paths accordingly. 我建议在根目录内使用单个package.json并相应地设置所有路径。

So I finally found the solution I was looking for. 因此,我终于找到了所需的解决方案。 My code base has the following structure. 我的代码库具有以下结构。

app/
client/
public/
...

I'm currently building my client solution as @yeasayer suggested above. 我目前正在按照上面@yeasayer的建议构建客户端解决方案。 After building and deploying my react project to the public folder in my rails api, I added the following to my routes: 在将我的react项目构建并部署到rails api中的公用文件夹之后,我在路由中添加了以下内容:

... # api routes ...

get '/*path', to: 'react#index'

Then I created a react_controller and added the following contents: 然后我创建了react_controller并添加了以下内容:

class ReactController < ActionController::Base
  def index
      render :file => 'public/index.html', :layout => false
  end
end

Now any routes not caught by the api routes, will render the react app. 现在,任何未被api路由捕获的路由都将呈现react应用。 I'm not sure why others don't use this structure instead of using react_on_rails or some other plugin to achieve the same result. 我不确定为什么其他人不使用此结构而不是使用react_on_rails或其他插件来达到相同的结果。 This setup is a lot simpler than dealing with these other solutions but I'd like to hear any thoughts on why this solution is not a good idea. 此设置比处理其他解决方案要简单得多,但是我想听听有关为什么此解决方案不是一个好主意的任何想法。

I see you are using the create-react-app-buildpack, but I think your issue is that your react app is in a subdirectory. 我看到您正在使用create-react-app-buildpack,但我认为您的问题是您的react应用程序位于子目录中。 Buildpacks only get executed if heroku can detect a matching application in the directory and since your package.json in your root does not match create-react-app-buildpack I don't think it is being used. 仅当heroku可以在目录中检测到匹配的应用程序时才会执行Buildpacks,并且由于您根目录中的package.json与create-react-app-buildpack不匹配,因此我认为它没有被使用。

What you might try is removing the root package.json and using this sub directory buildpack so you can specify the locations of each buildpack directory 您可以尝试删除根package.json并使用此子目录buildpack,以便您可以指定每个buildpack目录的位置

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM