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 getasset_path
andasset_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?
About the Author