In part 1 of this mini-series we covered Starting an Angular 4 app on Rails 5 from scratch. This part will take that app and launch it on Heroku.
Should you use the Rails Asset Pipeline?
asset_url into your Angular code. This was not an optimal solution to me.
My requirements were as follows:
rails slocally to dev w/the best of the hot reloading, etc that comes with the webpack setup that comes with the Angular CLI.
git push origin masterand have Herokou build everything and launch my app
Seems simple enough, but there's some config required. Let's get started.
1. Convert/copy package.json
In order for Heroku to build, it needs to know how to build angular, as well as build rails. This means at very least it needs a package.json file with a
heroku-postbuild script. In my experience it needed more than this. I ended up copying all the dependencies and dev dependencies into the package.json file of the root of the directory. I also did not remove the package.json from the /angular directory. When I did this, it caused other troubles. I don't like part of the solution, but it's what is working for now. Iteration!
So in the end you should have a
package.json at the root of your directory that looks something like this:
heroku-postbuild step will be run after Heroku runs
npm install. This makes sure that the Angular CLI is available so that
ng build can be run.
Running --prod and --output-hashing=none took me a while to get right, as it seems that --prod fails on a more strict set of typescript rules. Strange. I'm sure it's something I'm doing.
2. Convert/copy .angular-cli.json
The next step is to copy the Angular CLI json file (.angular-cli.json) to be at the root level of your angular app.
Once copied from the /angular/.angular-cli.json, I had to change the "root" and "outDir" and a few other bits of the file to look inside the angular subdirectory:
This tells Angular CLI where to look for its files. At this point, run
npm run prod and confirm that the CLI compiles your project and dumps it in the /public directory of rails.
3. Setup Rails 5 to serve the Angular 4 App
This part isn't Rails 5, nor Angular 4 specific, you can use it on a multitude of types of front-end applications.
config/routes.rb to add a root and an '*unmatchedroute' route.
These two routes will send / to the front-end app, and any other routes that aren't dedicated to Rails (hence why I scope everything else under /api) get swallowed up by the front-end as well, and Angular handles the routing.
This route does no good without a controller to match. Create a file at app/controllers/pages_controller.rb, and paste the following (it'll be the easiest controller you ever write).
Now we need a view to load up the front-end app. I'm going to copy a fair bit of code from the generated index.html built by
ng build --prod. Create a file at
app/views/pages/index.html.erb and paste in the following:
You may now need to go edit
app/views/layouts/application.html.erb and add the following to the head section:
4. Setting up Heroku
I'm going to assume you've already got Heroku setup to read your git repo and build from master.
In this order, add the following buildpacks (the only way to re-order is to remove and re-add):
Once those things are added, you should be able to push to master, watch it build, and everything should spin up correctly. Don't forget to make sure your database and any other settings you need are already setup.
Hint: try tailing the logs
heroku logs --tail --app myapp
I don't like how the package.json has to be setup. But I also didn't like being tied to the Rails asset pipeline. For now I feel like this provides the best solution, and it's working for my current app. Hope it works for you or at least points you in the right direction!