Today I found an interesting edge case in using Sass or SCSS in Rails with the asset pipeline.
The manifest file in this Rails application was an application.scss
file and was using @import
statements instead of require statements.
However, two of the lines were:
css
@import "chosen/chosen.css";
@import "flowplayer/flowplayer.css";
These look innocent enough. But when the application was deployed to production, the application.css
file started with
css
@import url(chosen/chosen.css);
@import url(flowplayer/flowplayer.css);
html,body,div,span,applet...
Which was then causing a Failed to load resource: the server responded with a Matenia Rossides4 (Not Found) status as the browser was trying to load, individually, the chosen and flowplayer CSS files as individual files outside of the asset pipeline. What gives?
Well, reading the Rails Guide on the Asset Pipeline I found the section that stated:
"If you want to use multiple Sass files, you should generally use the Sass @import rule instead of these Sprockets directives. When using Sprockets directives, Sass files exist within their own scope, making variables or mixins only available within the document they were defined in."
Following the link to the Sass @import rule, I found that there were a couple of situations where instead of importing the file, it will compile the @import into a CSS import command.
So the fix was removing .css
from the end of both files, and voila, magic happens, the import statements are no longer compiled into CSS import commands but inlined into the generated application.css
as expected, which made the mainfest file look like this:
css
@import "chosen/chosen";
@import "flowplayer/flowplayer";
Then re-running the assets:precompile
rake task as part of the OpsCare deployment in production solved the problem.
Hopefully this helps someone else not lose the hour I just lost :)