Ruby
Article

Automatically Reload All the Things with Guard

By Jesse Herrick

Imagine yourself in this situation:

It’s a brisk afternoon at the office and you’ve been slaving away at a front end project for the last twelve hours. You’ve repeatedly had to go through the whole save-compile-reload phase with your browser. And when I say compile, I mean compile those SCSS and CoffeeScript files that you so desperately wanted with a series of painstaking shell commands. “I’m a Rubyist!”, you shout, “there has to be a better way!”. Well, there is. Allow me to introduce you to Guard, your new favorite Ruby gem for the front end.

What is Guard?

Guard is simply a file system watcher. In other words, it detects when you save a file, then runs a command. It’s a little more complex than that, but we’ll cover that next.

How Can Guard Help Me?

Remember that scenario that you were just in? Well, this time let’s insert Guard into it:

It’s a brisk afternoon at the office, but you don’t mind because you just finished your latest front-end project. At your standing desk (yes, you’re that cool), you have a few windows open. On your large monitor, your favorite code editor is open with a terminal minimized for easy access. On your laptop’s screen, there is a browser window open. You haven’t had to touch this window for hours, because Guard and LiveReload are automatically updating the browser based on your changes. This includes compiling your SCSS and CoffeeScript! You take a sip of your coffee and shout, “I’m a Rubyist!”, while looking around at your coworkers, who are still going through the save-compile-reload phase. Life is good, all thanks to Guard.

Do you want this? Of course you do! Let’s get started…

Installing Guard & Friends

Installing Guard is as easy as gem install guard. Then you’re ready to get setup.

Next, you have to decide which plugins you want. In this tutorial, we’re going to discuss the following plugins: (you will need to install them: gem install PLUGIN)

Each plugin is a little different, but also a lot the same. Once you learn how to set up these 5 plugins, you’ll be able to setup the other 267+ available guard plugins.

For most projects, it’s advisable to have a Gemfile for dependencies. Here’s what your Gemfile should look like if you’re using all of the plugins:

source 'https://rubygems.org/'

group :development do
  gem 'guard'
  gem 'guard-coffeescript'
  gem 'guard-sass'
  gem 'guard-less', git: 'git://github.com/guard/guard-less.git'
  gem 'therubyracer'
  gem 'guard-livereload'
end

Note: At this point in time, it is necessary to build the guard-less gem from git because the maintainers have not pushed the latest version to RubyGems. This may change, but right now, this is how it is. (see issue #16) You can try it without the git option, but I cannot guarantee an error-free installation. Also, the gem therubyracer is required by guard-less, but not used as a dependency, so we have to add it ourselves.

CoffeeScript

You’re a Rubyist. Admit it, and the Ruby-esque syntax of CoffeeScript lured you from the beginning. With guard-coffeescript you no longer have to decide between ugly JavaScript or an ugly compile process with CoffeeScript. Let’s initialize Guard with CoffeeScript:

$ bundle exec guard init coffeescript

This generates a configuration file (Guardfile) for your “guards” (plugins). Let’s take a look inside:

# A sample Guardfile
# More info at https://github.com/guard/guard#readme

guard 'coffeescript', :input => 'app/assets/javascripts'

That’s very nice, but we keep our CoffeeScript in a different directory than the compiled JavaScript, so let’s change the file:

guard 'coffeescript', :input => 'coffee', :output => 'js'

Notice that we added :output to the options. This way, CoffeeScript lives in the coffee directory and is compiled to the js directory.

Start up guard and see it watch our files:

$ bundle exec guard

Add a little CoffeeScript to our project and save:

# file: coffee/test.coffee

console.log 'It worked!'

Notice in the terminal that when you save the file, it generates the JavaScript in the js directory:

[1] guard(main)> 
20:54:21 - INFO - Compile coffee/test.coffee
20:54:21 - INFO - 08:54:21 PM Successfully generated js/test.js

When you save any *.coffee file in the coffee directory, Guard will compile it to the js directory using the same name. It’s as simple as that.

Sass/SCSS

Come on, we all love Sass/SCSS. The process is very similar to that of CoffeeScript. In fact, we’ll even build on to the same Guardfile. The guard-sass plugin does have an init template to start out with, but this time we’ll make it ourselves. Luckily it’s pretty simple:

guard 'sass', :input => 'scss', :output => 'css'

It’s exactly the same configuration as guard-coffeescript, and it does pretty much the same thing. All Sass/SCSS files inside of the input directory (scss in this case), will be compiled into the output directory (css). Nice and easy; just the way it should be.

Less

Less’ config is a little different than guard-coffeescript and guard-sass. It uses regular expressions and the watch method inside of a block. This may seem a little confusing, but you’ll understand in a minute.

guard :less, output: 'css' do
  watch %r{^less/.*\.less$}
end

This example shows a guard :less block with a watch method. watch takes a regular expression that matches all files in the project. In this example, the regular expression matches all files that are in the directory less and have a .less extension. If you’re unfamiliar with regular expressions, you can play around with this one here. Note that %r{} and // are evaluated as regular expressions in Ruby. However, with the %r syntax, forward-slashes (‘/’) do not need to be escaped. We could just as easily write the same thing like so:

guard :less, output: 'css' do
  watch /^less\/.*\.less$/
end

Let’s run Guard and test this out:

$ bundle exec guard

Now, create a less file in the less directory.

// file: less/foo.less
@black: #000;

body {
        background: @black;
}

Once saved, notice that foo.css is compiled into the css directory because of the :output option.
GEG

LiveReload

We’ve handled asset precompiling, but what about the “refresh” part of “save-compile-refresh”? Say hello to guard-livereload, because it just made your life a lot easier.

What is LiveReload?
LiveReload is a browser auto-refresh utility. Guard tells it when files change and LiveReload (in your browser) automatically updates the page.

Installation
We’ve already included guard-livereload in our Gemfile, so it should be installed, but we also have to install the Chrome extension. You can download it here. Now, let’s configure guard-livereload.

Here is a list of the assets that we want to be reloaded on save:

  • HTML
  • CSS
  • JS
  • PNG
  • JPG

Notice that we did not include Sass, SCSS, Less, or CoffeeScript, because those will be compiled and reloaded by LiveReload as they change. It’s a beautiful cycle. Let’s create the regular expression to make it all happen.

The regexp is: %r{^.*\.(html|css|js|png|jpg)$}. Feel free to test this at rubular to make sure that it works the way we want.

Put this into the Guardfile like so:

guard 'livereload' do
  watch %r{^.*\.(html|css|js|png|jpg)$}
end

If we save any files matching the regular expression, the browser will reload said riles. But first, we have to link the extension to Guard. To do this, let’s create a simple HTML file:

<!DOCTYPE html>
<html>
  <head>
    <title>Guard Rocks!</title>
    <link rel="stylesheet" href="css/foo.css">
  </head>

  <body>
    <h1>Hello, Guard!</h1>
  </body>
</html>

Nothing special, just good ol’ HTML. Since it’s a static file, you may visit it using the file:// protocol, but Chrome is very restrictive on extensions accessing local files (and for good reason), so we should serve our files using a simple server. Ruby to the rescue once again!

Create a file called serve.rb in the root of your project.

# file: serve.rb

require 'rack'

server = Rack::Builder.new do
  run Rack::Directory.new(Dir.pwd)
end

Rack::Handler::WEBrick.run(server)

This is just a simple Rack/WEBrick server that will host our files on localhost:8080. Run ruby serve.rb and you’re good to go! You can shutdown the server at any time with control-C.

Now, we can visit this in our browser at localhost:8080/index.html. To connect the extension to Guard, click the LiveReload button in your browser extensions bar, and Guard should output “Browser connected”. This will not work until the browser is connected.

Let’s say that we want the text in the body to be white. All we have to do is enter color: #ffffff into our body selector. Once this is done, Guard will compile your SCSS/Sass/Less into CSS and reload the browser, immediately showing your changes. The same works for JavaScript/CoffeeScript files. Awesome!

Notifications

I hear you shouting at your computer. You’re saying, “Wow! This is super awesome! I just wish I could get notifications on my computer screen so I don’t have to look at my terminal for confirmation of a build.” Lucky for you, Guard allows this to be done pretty easily. However, it varies from system to system. Let’s get started in my favorite to least favorite operating systems.

A Note for the LESSers out there:
The Guard-LESS plugin does not support notifications at the moment. It’s actually terribly maintained, so if you’ve got some free time, maybe fork it.

Mac OS X

For Mac, we’ll be using something called Growl. It should be noted that Growl is not free, but it is open source. So if the $4 (which goes directly to the project) is too much for you, you can try building it yourself. You can find instructions for that here, although it will probably be a painstaking process.

Once you have Growl installed, add gem 'ruby_gntp' to your Gemfile and bundle install. Guard and Growl work great together, so they need absolutely no other setup than having Growl running:

$ bundle exec guard
14:54:30 - INFO - Guard is using GNTP to send notifications.
14:54:30 - INFO - Guard is using TerminalTitle to send notifications.
14:54:30 - INFO - Guard::Less 1.0.0 is on the job!
14:54:30 - INFO - Guard::Less: compiling all files
14:54:30 - INFO - Guard::Less: Skipping less/foo.less because css/foo.css is already up-to-date
14:54:30 - INFO - Guard is now watching at '/path/to/project'

Now, any time we change a file, Growl + Guard will let us know.

Growl Notification from the Sass Plugin for Guard

Linux

For Linux, we have two methods: Growl for Linux and Libnotify.

Growl for Linux

Install Growl for Linux and add gem 'ruby_gntp' to your Gemfile, then run bundle exec guard and you’re good to go!

Libnotify

Install libnotify-bin in your favorite package manager (sudo apt-get install libnotify-bin), add gem 'libnotify' to your Gemfile, then run bundle exec guard.

Note: This may not work on all Linux distributions.

Windows

Guard suggests either Growl for Windows or Snarl. Once you have installed one of these, just add gem 'ruby_gntp' to your Gemfile and bundle exec guard.

Disclaimer: I have not tested either of the Windows methods and cannot guarantee success.

Rails (RSpec)

You started drooling at the thought of Guard on Rails didn’t you? Let’s make this magic happen. The situation is similar to the ones above: You’re working on a Rails application and running the same test commands over and over again is getting tedious. Don’t worry, Guard’s got your back.

  1. Add gem 'guard-rspec' to your Gemfile (and bundle install).
  2. Run guard init rspec to create a standard project scaffolding.
  3. Run bundle exec guard and watch the magic.

It’s that simple. However, I can safely assume that you like to customize things, so let’s modify the Guardfile a little. First, here’s what Guard gives us:

# A sample Guardfile
# More info at https://github.com/guard/guard#readme

# Note: The cmd option is now required due to the increasing number of ways
#       rspec may be run, below are examples of the most common uses.
#  * bundler: 'bundle exec rspec'
#  * bundler binstubs: 'bin/rspec'
#  * spring: 'bin/rsspec' (This will use spring if running and you have
#                          installed the spring binstubs per the docs)
#  * zeus: 'zeus rspec' (requires the server to be started separetly)
#  * 'just' rspec: 'rspec'
guard :rspec, cmd: 'bundle exec rspec' do
  watch(%r{^spec/.+_spec\.rb$})
  watch(%r{^lib/(.+)\.rb$})     { |m| "spec/lib/#{m[1]}_spec.rb" }
  watch('spec/spec_helper.rb')  { "spec" }

  # Rails example
  watch(%r{^app/(.+)\.rb$})                           { |m| "spec/#{m[1]}_spec.rb" }
  watch(%r{^app/(.*)(\.erb|\.haml|\.slim)$})          { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
  watch(%r{^app/controllers/(.+)_(controller)\.rb$})  { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
  watch(%r{^spec/support/(.+)\.rb$})                  { "spec" }
  watch('config/routes.rb')                           { "spec/routing" }
  watch('app/controllers/application_controller.rb')  { "spec/controllers" }
  watch('spec/rails_helper.rb')                       { "spec" }

  # Capybara features specs
  watch(%r{^app/views/(.+)/.*\.(erb|haml|slim)$})     { |m| "spec/features/#{m[1]}_spec.rb" }

  # Turnip features and steps
  watch(%r{^spec/acceptance/(.+)\.feature$})
  watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$})   { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
end

You may decide that you want all of these things, but I like to simplify things a bit:

guard :rspec, cmd: 'bundle exec rspec' do
  watch('spec/spec_helper.rb') { "spec" }
  watch('config/routes.rb') { "spec/routing" }
  watch('app/controllers/application_controller.rb') { "spec/controllers" }
  watch(%r{^spec/.+_spec\.rb$})
  watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
  watch(%r{^app/(.*)(\.erb|\.haml|\.slim)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
  watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
  watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
end

This will cover all (or, at least, most) of the tests that are typically run in a Rails app. This should save you and your fingers from all that extra test running. One thing that I would like to note in this code is the cmd option. This specifies which test command will be run. In this situation, it’s bundle exec rspec, but it could just as easily be bundle exec rake test; each project will be different.

As you’ve seen, Guard is a fantastic tool for anything automated. You can watch a project for file changes then compile, test, or even reload a browser window. Save yourself frustration and get Guard.

  • istrasci

    I love guard-livereload, but in the last few weeks, it’s stopped working for me in Chrome. Have you experienced this at all?

    • JesseHerrick

      I haven’t had any issues. You might want to try reinstalling the extension.

      • istrasci

        Yeah, that seemed to work. Don’t know why it suddenly stopped working.

  • JoshuaMuheim

    what about reloading spring after the gemfile changed? this is the only thing i’m still missing since a long time, and nobody seems to care about…?

Recommended

Learn Coding Online
Learn Web Development

Start learning web development and design for free with SitePoint Premium!

Get the latest in Ruby, once a week, for free.