Persisting SCSS variables in rails asset pipeline?
Asked Answered
P

4

23

I'm upgrading a rails app with lots of SCSS stylesheets to use the asset pipeline, and need to include some global variables and mixins for each file.

Adding several @import directives at the top of every file isn't very DRY, so I'd like to do something like this:

# application.css
/*
*= require variables
*= require mixins
*= require_tree .
*/

This doesn't work of course, because the variables are not persisted across files. Anyone know how to achieve this?

Pelvis answered 16/1, 2012 at 23:35 Comment(0)
S
43

The default manifest syntax isn't powerful enough to give you useful Sass features like shared variables, mixins, etc. Instead, you should:

  1. Rename application.css to application.scss (or application.css.scss in Rails 4 or earlier)
  2. Instead of using the

    /*
     *= require variables
     *= require mixins
     *= require_tree .
     */
    

    nonsense, you should now use

    @import "variables";
    @import "mixins";
    @import "blah"; // import each SCSS file in your project like this.
    

    This will ensure you have full benefit of your variables and mixins throughout your project, and you are kept as DRY as Sass allows.

Saire answered 24/4, 2013 at 17:7 Comment(5)
Agreed. This is what I've been doing too.Pelvis
An annoyance worth pointing out with this solution is that all of your css ends up in one file. The idea with application.css is that it still loads each css file separately (in dev) which can help with QA as you know every file being included in your network traffic. (Granted with sass you can still inspect issues and see the .scss file it came from in the comments added by SASS)Portwine
I believe you can have rails output source maps (fonicmonkey.net/2013/03/25/…), so you can inspect the source files directly.Saire
Can you still use /*= require_tree . while using the new @import syntax?Kulda
@MikeC yes, but you lose the benefit of reusing mixins or variables, etc. when you don't use @import. So it's best to just switch entirely to @import.Saire
M
8

Simply importing the necessary file from each Scss or Sass file seems to have worked for me. For example, I have a colors.scss file that includes some constants like this:

$black: #222;

I require it in my application.css manifest along with some other files:

/*
 *= require colors
 *= require buttons
*/

In my buttons.css.scss file, I simply do this to avoid the error:

@import "colors";
Mat answered 6/7, 2012 at 1:2 Comment(1)
That does not solve the problem. The goal was to avoid the need to import them from each scss file. Your answer is the same as mine. Thanks anyway :)Pelvis
P
3

Doesn't seem to be possible. Ended up prepending each file with @import 'includes/all'; and including everything else from includes/all.css.scss.

Pelvis answered 23/1, 2012 at 1:3 Comment(0)
W
0

Replace require with @import and remove any = require even if you think you've commented it out.

Whitelaw answered 9/10, 2019 at 18:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.