I like Sass and I like Heroku, but they don’t necessarily like each other. Because of Heroku’s read-only file system and Sass’s tendency to write files to disk, a workaround is needed to get the two to play nicely together. Heroku’s own blog suggests a solution where Sass writes its generated css files to the Rails
/tmpdirectory (a writeable directory in the eyes of Heroku) and they even give you aplugin to do it. Unfortunately, that plugin is deprecated…and its successor, Hassle, doesn’t quite work either. Luckily, I found a version that works for my setup (Rails 3.0.3, Sass 3.0.24 at the time of this writing) by Jakob Skjerning. With this I was able to get a single Sass file to work in production on Heroku.
I like to have one
application.sass that imports a bunch of other files (e.g.
layout.sass, etc.) using the
@import directive. This causes my stylesheets to be compiled down to one file:
application.css. For some reason, when I tried to use a mixin in an imported file, given the mixin was defined in yet another file, I received this error:
Undefined mixin 'roundcorners'. (Sass::SyntaxError)
Hassle uses Sass’s
#update_stylesheets to compile the css, which attempts to compile each Sass file in alphabetical order. Because of my directory structure Sass was unable to find the mixin definition, thus generating the error .
After reading more about the
@import directive I discovered a couple of neat tricks. First, the ability to add multiple files to a single call, so instead of:
@import reset.sass @import mixins.sass @import colors.sass
I was able to write:
@import "reset", "mixins", "colors"
Notice you can also drop the extensions.
The next (and more important) trick, if you prepend an underscore to your Sass file name (i.e.
_mixins.sass instead of
mixins.sass), it won’t be compiled to css. By skipping the compilation of these imported files I was able to avoid the above error and everything worked as expected. (You import the Sass files as usual, leaving off the underscore.)
On a related note: I don’t like to keep the generated css files under version control because these can often cause unnecessary conflicts. Suppose you changed your Sass styles, but didn’t refresh your browser. If you then commit, and later your Sass file compiles to css, you will have an astranged diff that doesn’t really deserve a commit (or should have been lumped in with another). Another example, my
colors.sass…it is just a collection of hex values assigned to variables…there is no reason for a css version of this file.
Now go get Sassy with Heroku! (oh, and quit picking on Haml!)