Bower, Rails, and Javascript Components With CSS and Images

- - posted in Bower, Javascript, Rails

There are a number of good articles describing the setup of bower with rails applications, but I was having a hard time finding a good description for how to integrate Bower, Rails, and javascript components that contain CSS and images. Specifically, I was trying to use bower to manage my applications dependency on select2.

TL;DR;

Use the bower-rails gem.

It provides a number of nice rake tasks that help integrate the use of bower with a rails application and the asset pipeline. I prefer to stick with the bower.json configuration instead of the ruby-based DSL that bower-rails provides. I stick with the default bower location that stores assets in vendor/assets/bower_components. Make sure to add the following to your application.rb.

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

Once you have packages added to your bower.json, then you run the following:

rake bower:install

to install your javascript packages. You then reference the javacript in your application.js and application.css files.

For javascript components that reference images within their CSS, you need some mechanism for updating the asset paths to be rails asset pipeline friendly. Bower-rails aids in fixing this issue with the provided rake task:

rake bower:resolve 

It resolves relative asset paths in components by rewriting url references in component css files with the rails helper method to reference the asset in an asset pipeline friendly way. See BowerRails::Performer#resolve_asset_paths for more detail.

My preference is to check in all of the bower_components into our repository, so we run bower:install followed by bower:resolve. You then need to add the images referenced within the package to your config.assets.precompile list for your staging and production environments. For example here is the setup for adding the select2 javascript component to your rails project using bower and rails.

bower.json:

{
    "name": "Acme",
    "private": true,
    "dependencies": {
        "select2": "3.5.1"
    }
}

app/assets/javascripts/application.js.coffee:

#= require select2/select2

app/assets/stylesheets/application.css.sass

//= require select2/select2

config/environments/staging.rb and config/environments/production.rb:

config.assets.precompile += ["select2/*.png",
                            "select2/*.gif"]

It’s not perfect, but it gives you the dependency management of your javascript components, and it’s better then trying to figure out what gems you need to pull in to get the desired javascript component enabled for the asset pipeline.