预编译SCSS:变量未定义(Rails 4)

时间:2014-08-14 14:23:50

标签: ruby-on-rails asset-pipeline

场景

/products.css.scss

@import 'partials/colors';
@import 'partials/boxes';

#wrapper {}

/partials/_colors.css.scss

$light-gray: #ccc;

/partials/_boxes.css.scss

#box-light-gray {
  background-color: $light-gray;
  width: 50px;
  height: 50px;
}

问题

它发生在rake assets:precompileproduction环境中:

  

Sass :: SyntaxError:未定义的变量:" $ light-grey"。     (在/partials/_boxes.css.scss:2中)

我的想法

文件 /partials/_boxes.css.scss 本身并没有变量$light-gray - 在这里我必须同意rake assets:precompile。重点是:如何让rake识别$light-gray注入 /partials/_boxes.css.scss

我认为rake与谜题的点不匹配,因为它不知道SCSS是如何工作的。我觉得我错过了与rake相关的SCSS相关内容。

2 个答案:

答案 0 :(得分:7)

当前版本的Sprockets和sass-rails这是一个棘手的问题。您会认为*= require文件中的application.css行会按顺序加载变量,以便它们可供所有scss文件使用,但事实并非如此。以下是asset pipeline Rails guide对此的说法:

  

如果你想使用多个Sass文件,你通常应该使用   Sass @import规则而不是这些Sprockets指令。运用   Sprockets指令所有Sass文件都存在于自己的范围内,   使变量或混合仅在文档中可用   定义在。你可以使用@import“”进行文件通配,   和@import“* / *”添加相当于如何的整个树   require_tree有效。有关详细信息,请查看sass-rails文档   和重要的警告。

换句话说,您有两个选择:

  • @import您需要的每个文件中的变量
  • @import文件中使用application.css.scss代替*= require

如果你选择第一个选项,只需将@import 'partials/colors';放到_boxes.css.scss的顶部。

使用第二个选项,您只需@import application.css.scss一次sass-rails样式表(按照正确的顺序),然​​后mixins中的变量将可用于所有样式表。你仍然在这里使用资产管道,所以预编译仍然可以正常工作,但是你要让application.css.scss使用它的魔法。您的@import 'partials/colors'; @import 'partials/*'; @import '*'; 看起来像这样:

.erb

但请注意,目前有bug个sass-rails。如果你有{{1}}个样式表,如果它们位于一个单独的文件夹中,sass-rails将无法通过通配符导入它们。

答案 1 :(得分:2)

如果不修改您的scss,我认为您最好的选择是将@import 'partials/colors';放入_boxes.css.scss文件中。 @import的最大缺点是它包含一个额外的http请求,但是由于您正在预编译您的资产,我不完全确定这仍然是一个问题。

潜在的重构选项:

_colors.css.scss

$light-gray: #ccc;

_box-sizes.css.scss

.small-box{
   width: 50px;
   height: 50px;
}

products.css.scss

@import 'partials/colors';
@import 'partials/box-sizes';

.small-light-grey-box{
    @extend .small-box
    background-color: $light-gray;
}

同样,这只是一个例子。有无数种方法可以重构你的scss和html来获得理想的结果。