The essentials of this process are covered well in the Rails-centric article that has been the inspiration for this series, but I'll whip through it here as there are a couple of changes to make it work with Play.
First, we drop a package.json into the project root, that describes the front-end packaging process to Heroku:
{ "name": "build-client-on-heroku", "engines": { "node": "6.3.1" }, scripts": { "build": "cd client && npm install && npm run build && cd ..", "deploy": "cp -a client/build/. public/", "postinstall": "npm run build && npm run deploy && echo 'Done!'" } }
Next, we add a Heroku buildpack to the front of our Heroku build chain, to assemble the Node front-end prior to booting Play:
% heroku buildpacks:add heroku/nodejs --index 1 % heroku buildpacks === myapp Buildpack URLs 1. heroku/nodejs 2. heroku/scalaAnd, as documented in the above-linked article, we set an NPM environment variable that will get react-scripts (which is declared as a devDependency by create-react-app) to be installed as needed:
% heroku config:set NPM_CONFIG_PRODUCTION=false
We're almost there. But before you git push heroku master, there's one extra bit of configuration to perform to make Play serve up our React app as expected. You might have noticed the deploy step up there in that package.json where we copy the result of the NPM build into public. If we just leave everything as-is, we'll only be able to access the React front-end by using https://myapp.herokuapp.com/assets/index.html - which is almost certainly not what we want.
A couple of extra lines in conf/routes will fix this right up:
# Our backend routes (e.g. serving up JSON) come FIRST: GET /dummy-json controllers.DummyController.dummyJson # Last of all, fall through to the React app GET / controllers.Assets.at(path="/public",file="index.html") GET /*file controllers.Assets.at(path="/public",file)Because of the use of wildcards, order is very important here. Backend endpoints come first, then the / route which captures the age-old "index.html is the default page" web convention, and finally a catch-all that ensures all the other artefacts of the NPM bundling get served up by Play's Assets controller.
And there we have it! A Create-React-App+Play stack. The CRAP stack! Despite the unfortunate name, I hope this has been a useful and inspirational starting point to build something great with these amazing (and free) technologies.
No comments:
Post a Comment
Comments welcome - spam is not. Spam will be detected, deleted and the source IP blocked.