Close
Glad You're Ready. Let's Get Started!

Let us know how we can contact you.

Thank you!

We'll respond shortly.

LABS
Giving Rails 2 the Asset Pipeline

We had a client project, a Rails 2 app, that needed some cleanup around JavaScript and CSS management. They were using both Sprockets 1 and Jammit, as well as a bunch of plugins and gems to help make all this work together. They had a set of problems that the Rails 3.1 Asset Pipeline solved. But due to gem dependencies we couldn’t go to Rails 3 yet.

How hard could it be to put Sprockets 2 and the Asset Pipeline into a Rails 2 app?

1. Add Sprockets 2

In the Gemfile:

gem sprockets, "~> 2.0"

2. Working with SASS

If you need/want the Sass gem for SASS or SCSS stylesheets, then this goes in the Gemfile:

gem 'sass'
group :development, :test do
  gem 'sprockets-sass'
end

Rails 2 doesn’t include Sass by default. So you need to add it. Yes you might already have Sass if you’re using HAML for your view templates, but since they’re about to be broken apart, add it now.

The sprockets-sass gem adds support of watching individual .sass files in development and recompiling the parent stylesheet asset as needed. It’s not going to be used in production, but more on that later.

For your SASS files you’ll want to use @import to declare SASS dependencies instead of Sprockets’s require.

3. Rack it up in config.ru

Sprockets runs as Rack middleware, but since it’s difficult to map a path in Rails’s environment.rb. You need to make a new a rackup file, replacing the default Rails server rackfile, for your app that gives you `/assets` mapping in development. So copy below into your project root and name it config.ru so that the rest of Rails’s scripts (e.g., script/server) work with it transparently. For example:

What’s going on in this rackup file –

  • Sprockets with the same paths as Rails 3.1’s defaults – add more as necessary for your app
  • Guard against mapping /assets in production.
  • Guard against multiple loads if Rails is already initialized (a fix for testing)
  • Use Sprockets::Helpers to get asset_path and asset_url helpers (and others, see sprockets-helpers) for your stylesheets and views
  • Map / to the rest of Rails, guarding the middleware you don’t need in test

4. More Templates

Using EJS or Mustache? Then drop in the additional gems that work with Sprockets 2’s templating via Tilt:

gem 'ejs'
gem 'sprockets_spacely'

5. Move Your Assets

Now that configuration is done, move your assets under app/assets, just like the Rails Guide suggests. Don’t forget to change the url calls in your stylesheets to asset_url. Run the app, checking your JS console for 404s until all the includes and paths are correct.

6. Capybara

Capybara now needs to forget that it’s running Rails and instead just a Rack app. This technique (WARNING: eval ahead.), meant for using Cucumber/Capybara in a Sinatra app, works.

7. Compile your assets on deploy

All of this work so far makes your assets available from your /app directory in development and test. In production, they will get served from /public/assets. Rails 3.1 provides the assets:precompile to be used as part of the deploy process Generate an empty Rails 3.1 app and copy it into lib/tasks. Copy the Sprockets configuration from your config.ru into this task. Or yes, come up with a way to DRY this configuration up. Then you need to make sure it’s run at the right time during your deploy.

8. What’s left?

This was all we needed and it’s working well for this app. There are a few things that this guide doesn’t cover.

Assets from gems or /vendor are not loaded. Feel free to add explicit paths to Sprockets as needed. The Sprockets Helpers gem doesn’t yet support a Proc for an asset host, but there’s now an open issue on Github. This project didn’t need the former and we threw something together based on Sasset, which appears to be abandoned, and use it only on the asset compile step. We’re not using CoffeeScript on this project. These we’ll leave as exercises for the reader.

The Asset Pipeline is still a bit new and we’re all getting used to it. It’s not just Sprockets, SASS, etc. – there is a lot of functionality that Rails puts on top of Sprockets, but it’s easy enough to add the equivalents.

That wasn’t so bad, was it?

Comments
  1. Hi,

    Thanks for this. But, there were a few problems, at least in my config.

    Here is what I ended up that worked for this.

    # we need to protect against multiple includes of the Rails environment (trust me)
    require ‘./config/environment.rb’ if !defined?(Rails) || !Rails.initialized?
    require ‘sprockets’
    require ‘sprockets-helpers’

    unless Rails.env.production?
    map ‘/assets’ do
    sprockets = Sprockets::Environment.new
    sprockets.append_path ‘app/assets/images’
    sprockets.append_path ‘app/assets/javascripts’
    sprockets.append_path ‘app/assets/stylesheets’

    Sprockets::Helpers.configure do |config|
    config.environment = sprockets
    config.prefix = “/assets”
    config.digest = false
    end

    run sprockets
    end
    end

    map ‘/’ do
    use Rails::Rack::LogTailer unless Rails.env.test?
    use Rails::Rack::Debugger unless Rails.env.test?
    use Rails::Rack::Static
    run ActionController::Dispatcher.new
    end

  2. Ben Radler says:

    I found a very helpful, more up-to-date blog post that builds off of Davis’ solution here:

    http://jaredonline.github.io/blog/2012/05/16/sprockets-2-with-rails-2-dot-3/

    Highly recommended if you get stuck!

Post a Comment

Your Information (Name required. Email address will not be displayed with comment.)

* Copy This Password *

* Type Or Paste Password Here *