Ruby on rails 在Rails3.1中,是否真的不可能避免包含样式表的副本?

Ruby on rails 在Rails3.1中,是否真的不可能避免包含样式表的副本?,ruby-on-rails,sass,ruby-on-rails-3.1,Ruby On Rails,Sass,Ruby On Rails 3.1,当我试图在Sass样式表之间共享变量和混合时,遇到了一个令人不安的问题 如果我使用@import包含一个全局样式表——其中包括全局颜色、混合等——当Rails组合清单文件中引用的所有样式表时,它会再次被包含 或者,如果我的清单文件不包含全局样式表,但清单中的多个文件导入了全局样式表,则全局样式表仍将包含多次GAH. 你怎么能避开这个?Sass是否有秘密包含守卫?我做错了什么吗?我不明白为什么这是你具体问题的一个问题。变量和mixin声明不应在生成的css文件中导致任何选择器或声明块。但是,当您对

当我试图在Sass样式表之间共享变量和混合时,遇到了一个令人不安的问题

如果我使用
@import
包含一个全局样式表——其中包括全局颜色、混合等——当Rails组合清单文件中引用的所有样式表时,它会再次被包含

或者,如果我的清单文件不包含全局样式表,但清单中的多个文件导入了全局样式表,则全局样式表仍将包含多次GAH.


你怎么能避开这个?Sass是否有秘密包含守卫?我做错了什么吗?

我不明白为什么这是你具体问题的一个问题。变量和mixin声明不应在生成的css文件中导致任何选择器或声明块。但是,当您对多个选择器使用mixin时,每个选择器都包含相应的声明。这就是SASS处理它的方式

因此,只要只是变量和mixin,它们是否多次包含在清单文件中就不重要了,因为这对已编译的文件没有影响。在站点节点上,我认为SASS强制您显式声明每个文件的依赖项是一种很好的样式

但是,如果基础文件中也有选择器和声明,您希望从这些选择器和声明继承到不同的文件中,那么这些选择器和声明甚至会多次包含在编译文件中。了解如何通过配置来防止这种情况仍然很有趣。但是,如果您将每个sass文件视为一组封装的规则,而没有跨文件继承,那么您应该能够按照约定防止问题的发生

例如,当使用引导sass时,只需将mixin和变量定义引入范围

@import "bootstrap/variables";
@import "bootstrap/mixins";

您可以通过以下方式绕过此问题:

/* 
 * application.css.scss
 *= require_self
 * ----> Note the missing = require_tree 
*/  

@import "global.css.scss"; // Defines global mixins etc
@import "users.css.scss"; // Uses mixins defined in _global.css.scss
然后不要导入
global.css.scss
内部
users.css.scss
或任何其他相关文件


如果您还没有,请查看Ryan Bates,这就是他解决此问题的方法。

目前无法使用SASS动态包含文件
@import
不能在控制指令(例如,
@if
)或mixin中使用,在import指令中使用变量是错误的语法,并且没有提前结束文件执行的指令(这将允许条件导入)。但是,您可以通过更改样式规则的结构来解决问题

注 将
@import
修改为 包括文件一次。但是,

  • 您的代码将增加对环境的依赖性
  • 我们都会更好地理解样式规则是如何构建的,这将避免任何重复的规则
  • @import
    可能很快就会发布。SASS团队正在计划“重新进口保护” 可能是SASS未来版本的一部分 请求的功能
  • 解决方案 如果您的样式有条件地包含在多个文件中,则它们不是“全局”样式。这些样式应封装在mixin、“模块”或“库”文件中。其主要思想是导入一个这样的文件不会输出任何css。通过这种方式,您可以冗余地导入这些文件,这样您就可以在任何需要的地方使用mixin

    如果需要使用变量执行此操作,则:

  • 确保在包含mixin之前定义变量,否则它们仅在mixin中可用。这样做的一个好方法是在vars.sass文件中定义所有默认变量,并将其与导入的模块/库一起导入,以便这些变量在全局范围内可用
  • 使用
    定义变量!mixin中的默认值,因此即使在调用mixin之前也可以覆盖它(如在vars.sass文件中)
  • 如果要确保在没有严格包含规则的情况下定义顶级样式,则可以使用此混合:

    $was-defined: () !default;
    @mixin define-once($name) {
        @if not index($was-defined, $name) {
            $was-defined: append($was-defined, $name);
            @content;
        }
    }
    
    // Example:
    @include define-once('body-typography') {
        body {
            font-size: 100%;
            line-height: 2em;
            color: #444;
            font-family: monospace;
        }
    }
    

    要获得更多关于这样构造代码的良好实践,请查看。

    目前,在SASS 4发布之前,我更喜欢修改导入行,而不是类似以下内容:

    @if not-imported("font") { @import "font"; }
    
    您需要一个名为not imported的函数,当然,该函数如下所示:

    $imported-once-files: () !default;
    
    @function not-imported($name) {
      $module_index: index($imported-once-files, $name);
      @if (($module_index == null) or ($module_index == false)) {
        $imported-once-files: append($imported-once-files, $name);
        @return true;
      }
      @return false;
    }
    

    这可以很好地工作,并保持与其他工具(如StyleDocco)的互操作性。我写了这篇文章,

    我同意在每个文件中都有这一行,这样您就可以看到特定文件的依赖性是什么。但是在SASS中应该有一个简单的wau(或者更少),它允许您在清单文件中只包含一次文件(比如PHP require_once)。此外,如果有一种方法可以指定一个开关,将清单导入到它们自己的css文件中,那就太好了,以防您遇到IE 4095选择器限制,就像我的团队现在这样(尽管我们知道我们需要清理css)。请注意,这意味着当您进行更改时,依赖css文件将无法重建。我收到以下错误:“导入指令不能在控制指令或混合指令中使用。”@JorgeSampayo:您不能在此代码段中直接使用
    @Import
    。那将导致你提到的错误。如果使用我使用的代码,则不会出现此错误。错误标记在
    @If
    中的
    @import
    中。其中
    @if
    是控制方向您使用的是哪个SASS版本?哪种实现方式?Libsas?罗盘?sass(3.4.18)sass轨道(5.0.4)