When we heard the announcement of Ruby on Rails 3.1 RC, we agreed that we upgrade one of our internal applications and check out all of the new features.
This of course meant porting all of our asset packing and management from Jammit to Sprockets backed asset pipeline. Everything didn’t go as smooth as expected though.
The first issue I encountered with assets was that they were only concatenated in production, but not minimized or packed or anything like that. Now as we didn’t generate a new blank Rails 3.1 application, we missed out on some critical configuration variables (and the documentation on the new stuff is understandably pretty sparse at the moment). So to enable any kind of compression for your assets, you need to add the following configuration statements to your environment specific configuration file (these are default values in 3.1 applications).
config.assets.css_compressor = :scss
Now the second issue was a bit more weird – only a really small subset of the assets were being compiled with
I spent quite a lot of time tracking the cause for this behavior and finally stumbled upon the configuration for the assets feature:
The regexp is meant to find all of the non-css and non-js files in the asset paths and compile them – I’m guessing that this is mainly to handle SCSS and CoffeScript files (again the documentation is hard to come by).
As an unexpected side-effect it’s matching files like jquery.min.js and jquery.autocomplete.js, but not top-level assets like admin.js, which does not really seem to be the desired behavior.
There are basically two ways asset compiling would make sense:
- All of your assets get compiled: every single file from the asset path – from plain .css to .scss and .coffee files and manifests – get compiled and compressed. Then you just use whatever assets you like in your layouts.
- Only the top-level manifests are compiled: this means the files you are explicitly linking in your layouts, stuff like application.js and admin.css and so on.
Considering that you have top-level manifest files that group all of your dependencies, you rarely need to just use one single asset so I decided to go with the second option.
In order to only compile the top-level manifest files, you need to avoid the built-in regexp from being run and define the files your want to compile manually.
# just list all of your top level assets here
config.assets.precompile = %w( admin.js admin.css)
This does seem a bit verbose (especially if you have lots of top level manifests), but I prefer this over the default broken solution or a mess of files that compiling every single asset would result in.
Still not satisfied
There is one more thing that bugs me about the asset pipeline in Ruby on Rails 3.1 – if you reference a manifest file in your layouts in development mode, you will get a concatenated resource as the output.
a resource (basically the same as a manifest) and in development mode that resource is expanded into separate files, making debugging really easy as you know exactly which file you need to check etc.
And in production the same resource is concatenated and compressed into one single, small file.
I feel this is the way how assets should work in Rails 3.1 by default also – the benefit is pretty clear, at least for me.
Update: So it seems you can avoid having your assets being concatenated in development like this:
# or if you want to have debugging on automatically in development
Thanks for the tip, Bruno Michel!