Tuesday 20 September 2011

Asset Pipeline and Upgrading to Rails 3.1

One of the main changes in Rails 3.1 is the Asset Pipeline, which is, in the words of the Rails guide:
"The asset pipeline provides a framework to concatenate and minify or compress JavaScript and CSS assets. It also adds the ability to write these assets in other languages such as CoffeeScript, Sass and ERB.
Prior to Rails 3.1 these features were added through third-party Ruby libraries such as Jammit and Sprockets. Rails 3.1 is integrated with Sprockets through ActionPack which depends on the sprockets gem, by default.
By having this as a core feature of Rails, all developers can benefit from the power of having their assets pre-processed, compressed and minified by one central library, Sprockets. This is part of Rails’ “Fast by default” strategy as outlined by DHH in his 2011 keynote at Railsconf."
This looks like a really nice addition to Rails, and I look forward to enjoy its benefits. Unfortunately so far it has only brought me a slight feeling of pain, maybe because I have not started any Rails 3.1 application from scratch, but have only tried it by upgrading existing Apps from Rails 3.0 (or even from Rails 2.3.5) to Rails 3.1.

I first tried to upgrade to Rails 3.1 before the final release. It was a day to try new things at work and I had decided to upgrade an app from Rails 2.3.10 to Rails 3.1.rc1, and from Ruby 1.8.7 to Ruby 1.9.2. I started by upgrading the Ruby version, which wasn't an issue. Just had to recompile the gems I was using with the new version of Ruby and it all worked quite well.

Then I upgraded the Rails version to 3.0 by following Ryan Bates' Railscasts on the subject, and by using the Rails upgrade plugin. This took a bit longer as the application is relatively big, and quite a few things changed from Rails 2.3.x to Rails 3.0. I also had to add bundler as I was not using it before, but in the end I managed to do it.

Next step was upgrading to Rails 3.1. I thought it would be a challenge but it turned up to be quite simple... except for the Asset Pipeline. At that time not even the guide that I link to in the top was available, or at least I didn't find it, and I struggled to get my javascripts and css stylesheets to work. As the day was coming to an end I stopped there and haven't gone back to it since.

This week I had another go at upgrading an App to Rails 3.1. This time the application was in Rails 3.0.x, and once again everything went smoothly except for the Asset Pipeline.

My issue, I have found out, was related with the way I was using the application.js and application.css files. These files are used by Sprockets, the library that powers the Asset Pipeline, to know which js and css files are required by the application, they are named manifest files. In the different guides and documentation the examples of these files were something like:

So, in a noob action, I thought that the require_tree . directive would be enough to have all my javascript/css files properly included in the application. It turns out that, that, is not true. As some of my javascript files are dependent on other files my application was not working as expected, I needed to declare them in order in the manifest file for Sprockets to place them in order in the generated application.js file, and for the application to work.

I know this was probably my fault, but all the examples looked so tidy, and I didn't see any warning to be aware of this, that I was truly believing that Sprockets would make it all work. Like if it was magic!

Fortunately now I think that I got the hang of it and hopefully will be able to enjoy the power of the Asset Pipeline and of Rails 3.1.

For reference here are my manifest files, and they are not as tidy... If you know of a way to make them look better please let me know:


-----------------
Post-post: It seems that the guides state "For some assets (like CSS) the compiled order is important. You can specify individual files and they are compiled in the order specified:"... Guess another lesson is to try and read everything that is written in the Guides. :D Thanks to Décio to have pointed this out. =)