Search code examples
ruby-on-rails-4importsassturbolinks

Rails: drawbacks of using Sass's @import instead of *=require


I decided to use Sass's @import instead of Sprocket's *=require.

I have this in application.scss:

@import 'normalize';
@import 'font-awesome';
@import 'variables';

and this in blog.scss:

@import 'application';

This way I have separate stylesheets for separate controllers (makes my code more organized).

To make this work, I also added stylesheet_link_tag params[:controller] to my layout, then added Rails.application.config.assets.precompile += %w( blog.css ) line to my /config/initializers/assets.rb file and restarted the server.

Are there any drawback of this approach? Will turbolinks be slower?


Solution

  • The Rails Asset Pipeline guide actually recommends using Sass's @import instead of Sprockets *=require if you have multiple Sass files.

    Here's a quote from the Rails Asset Pipeline guide:

    "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. (http://guides.rubyonrails.org/asset_pipeline.html)"

    This is also recommended on the sass-rails gem Github page (https://github.com/rails/sass-rails). Here's a quote from that page:

    "Sprockets provides some directives that are placed inside of comments called require, require_tree, and require_self. DO NOT USE THEM IN YOUR SASS/SCSS FILES. They are very primitive and do not work well with Sass files. Instead, use Sass's native @import directive which sass-rails has customized to integrate with the conventions of your Rails projects."

    There aren't any significant drawbacks to this approach and there are actually quite a few benefits (including, but not necessarily limited to):

    1. The main advantages come from the fact that SASS @import creates a global namespace, while the Sprockets directives do not.

    2. Compilation will speed up a bit in development, because it won’t have to re-compile all the vendor mixins every time each partial @import’s it.

    3. Using the @import global namespace creates a Whorfian effect where the developers on the team tend to define and reuse their variables where they should (in the variables files), and not in more specific files. For example, z-indexes can become a nightmare if not defined in a global variables file (https://content.pivotal.io/blog/structure-your-sass-files-with-import).