Getting Rails and Bower to play nice

There are a number of resources and gems available for integrating Rails with Bower (providing Bower Rake tasks and other funky stuff), but really, much of that is unnecessary. Using gems often creates abstractions and leaves us relying on 'magic'.

At the end of the day, we want to use Bower to manage our front-end dependencies without getting into a muddle when it comes to the asset pipeline.

The asset pipeline can often present challenges and we certainly don't want to add to them, so let's take a really simple approach, using sensible defaults and a few convenient customizations.

If you don't already have Bower installed, now is the time to do that. Installations are well documented and I won't repeat them here. I recommend you get at least a little bit familiar with what these components do, but mastery is not required. There are essentially two options:

  • Install Bower globally ($ npm install -g bower), or:
  • Install Bower as a local Node module dependency ($ npm install --save bower).

With the first option, everyone on the project should install Bower globally using this same command.

With the second option, you will need a package.json file in your project root (often created with $ npm init) and new contributors will need to run $ npm install (assuming /node_modules is in your .gitignore file) to install Bower.

If the second option sounds like a whole lot more complication, go with the first option. For a Rails app, the second option doesn't really add any benefit and just using Bower globally is probably better.

Having decided on the above, the first thing you will need in your Rails project is a bower.json file. It seems sensible to put this in the root project folder. You can create it manually or use $ bower init (accepting the defaults is fine).

Before we start installing front-end dependencies with Bower; where do we want them to go? By default, Bower installs dependencies into [project]/bower_components. That's fine for a Node app, but as this is a Rails, I would be more satisfied if they went into [project]/vendor/bower_components.

Some recommendations suggest [project]/vendor/assets/bower_components as a location, but this doesn't feel right to me as it means putting bower_components, which will contain myriad source files, into a path intended for distributable assets. It doesn't really matter though, so choose whichever feels right for you.

Either way, we need to override the Bower default, which requires placing a .bowerrc file in the project root folder with the following content:

  "directory": "vendor/bower_components"

If you prefer to specify vendor/assets/bower_components instead, please go ahead; but look out for places (such as in the following section) where you will need to modify the examples.

Next we need to ensure vendor/bower_components is accessible from within the assets pipeline. In config/initializers/assets.rb add the following:

Rails.application.config.assets.paths << Rails.root.join('vendor', 'bower_components')  


Rails.application.config.assets.paths << Rails.root.join('vendor', 'assets', 'bower_components')  

...if you configured Bower to use vendor/assets/bower_components).

Next, you should decide whether or not to commit bower_components to your repository. For further discussion on this issue, have a look at Should you commit Bower components to Git?, which describes a few approaches.

Now let's check everything is working by installing a dependency. JQuery might be an obvious choice, but this is already bundled with Rails, so let's install Underscore instead.

Commit your changes to Git first so we are starting with a clean working directory. Next, run the following command:

$ bower install --save underscore

This will install all of Underscore's source files to vendor/bower_components/underscore. The --save bit will add the dependency to your bower.json file also. This means that irrespective of your approach to committing Bower components to Git, contributors to your project can always run $ bower install to install all of your project's Bower dependencies in one go.

Now, to reference Underscore in your Rails app, simply add the following to your app/assets/javascripts/application.js file:

//= require underscore/underscore