In my last post I discussed some of the attractive elements of the Clojure ecosystem. The primary Emberall app is still written in Rails and that’s still where most development happens, so I decided to take some time to enable the auto-refresh functionality built into Clojure’s Ring. Rails already gets us halfway there by automatically reloading updated files on the server, but by following these steps any open pages will also automatically refresh when code is updated in development.
Installing the Gems
Add the following two gems to your Gemfile
, then run bundle
and bundle binstub guard
:
Configuring Rails
The rack-livereload
gem takes care of bundling livereload.js and injecting it into all HTML pages served in development. To configure it, add the following lines to your environment:
For the full list of configuration options see rack-livereload.
Restart Rails, and verify that livereload.js
is correctly included in your HTML pages. Note that at this point your page should be trying to open a websocket to port 35729 unsuccessfully; we’ll fix that in the next step.
Configuring Guard
Configure Guard to watch your views
and assets
folder. I modified the default guard-livereload
template slightly to indicate that all of my SCSS files get included into application.css
, even in development. Other than that, this is the default Guard livereload configuration.
Running Guard
If you binstubbed Guard above you should now be able to run it simply with the bin/guard
command. If all goes well, as long as Guard is running making a change to a view or asset file will now automatically refresh the page with the new file!
Caveats
- We use Vagrant virtual machines for development, and Guard doesn’t pick up on filesystem changes for shared folders or remote NFS mounts. I got around this by using Vagrant’s relatively new rsync folder-sharing strategy. This actually improves performance compared to NFS or a shared folder in Virtualbox, but does introduce a second or two of lag in synchronization.
- If you use HTTPS in development (for example, to check that HTTPS is forced for certain routes) LiveReload will fail in Chrome because it attempts to open an unencrypted
ws://
websocket channel to the livereload server which is blocked for security reasons. From what I can tell guard-livereload doesn’t currently support TLS-secured websockets. If this is important to you, it should be possible to use stunnel as the websocket TLS termination and then pass the connection on to livereload.
Bonus – Livereload for Jekyll
Just for fun, I’ve also enabled livereload on this Jekyll-powered blog, which was quite straightforward (the only slightly tricky bit was using a custom Liquid template to include the Livereload javascript only in development). You can find all the source here.