Rails sass 编译中出现“错误:未定义的变量”

asc*_*man 5 ruby-on-rails sass sprockets

我正在构建一个 Rails 应用程序并遇到一些奇怪的 sass 编译问题。

我的设置:

  • 轨道 6.1.3
  • 红宝石3.0.0
  • sass-rails 6.0.0
  • sassc-rails 2.1.2

application.scss基本上加载了一些设置一些变量的 sass 文件,最后导入了layout.scss有效使用导入变量的文件。

// application.scss
@import "normalize";
@import "variables/colors";
@import "variables/typography";
@import "variables/sizes";
@import "layout";
Run Code Online (Sandbox Code Playgroud)
// variables/_typography.scss
$ui-font-family: "Poppins", sans-serif;
$ui-font-family-title: "Lato", sans-serif;
Run Code Online (Sandbox Code Playgroud)
// layout.scss
h1, h2, h3, h4, h5, h6 {
  font-family: $ui-font-family-title;
}
Run Code Online (Sandbox Code Playgroud)
// views/layouts/application.html.erb
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
Run Code Online (Sandbox Code Playgroud)

一开始它有效,但后来我注意到有时我会收到错误消息

Error: Undefined variable: "$ui-font-family-title".
        on line 3:16 of app/assets/stylesheets/layout.scss
>>   font-family: $ui-font-family-title;
Run Code Online (Sandbox Code Playgroud)

然而,有时在重新编译资产后(由于任何 scss 文件的更改),我注意到它要么工作,要么失败(出现该错误)。

@debug "Compiling filename"在每个 sass 文件中添加了一个来了解编译顺序,并发现一些对我来说非常奇怪的东西。

它总是对每个 sass 文件编译两次,问题是有时它只编译一次变量,因此在layout.scss第二次编译时会失败。

这是它工作时的样子:

工作版本

这就是失败时的样子:

在此输入图像描述

正如您所看到的,当它失败时,它会layout.scss连续两次编译文件,我的猜测是,由于在第二次迭代中它没有导入其他文件,因此它无法按预期找到变量。

您知道这里可能出了什么问题吗?

asc*_*man 9

我确实发现了问题。

看来在Sprockets 4.0上,它编译scss文件的方式是在这里定义的:

# app/assets/config/manifest.js
//= link_tree ../images
//= link_directory ../stylesheets .css
Run Code Online (Sandbox Code Playgroud)

这基本上会选择stylesheets文件夹中的任何 css/scss 文件进行编译。

因此,此问题的解决方案是是否更新清单以仅使用link您想要作为入口点的唯一文件,或者仅将该文件保留application.scss在文件夹的第一层中并将所有其他文件移动到子文件夹中,以便它们不是清单的目标。

我现在得到了这个,它有效:

// application.scss
@import "utils/normalize";
@import "variables/colors";
@import "variables/typography";
@import "variables/sizes";
@import "pages/layout";
Run Code Online (Sandbox Code Playgroud)

stylesheets/因此(至少在第一层深处)唯一的 scss 文件是application.scss.

您可以在此处找到有关链轮升级文档的更多信息:

您可能还会发现一些以前未编译为顶级目标的文件现在已编译为顶级目标。例如,如果您现有的应用程序直接在 ./app/assets/javascripts 或 css/scss 文件 ./app/assets/stylesheets 处有任何 js 文件,Rails with Sprockets 4 现在会将它们编译为顶级目标。因为他们以前没有被这样对待,所以你可能并不是故意的;如果它们是引用本应在其他文件中定义的变量的 .scss 部分,甚至可能会导致类似于“未定义变量:$some_variable”的错误消息。