问题描述
我正在构建一个 rails 应用程序,但遇到了一些奇怪的 sass 编译问题。
我的设置:
- Rails 6.1.3
- Ruby 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";
// variables/_typography.scss
$ui-font-family: "Poppins",sans-serif;
$ui-font-family-title: "Lato",sans-serif;
// layout.scss
h1,h2,h3,h4,h5,h6 {
font-family: $ui-font-family-title;
}
// views/layouts/application.html.erb
<%= stylesheet_link_tag 'application',media: 'all','data-turbolinks-track': 'reload' %>
<%= javascript_pack_tag 'application','data-turbolinks-track': 'reload' %>
Error: Undefined variable: "$ui-font-family-title".
on line 3:16 of app/assets/stylesheets/layout.scss
>> font-family: $ui-font-family-title;
但是,有时在重新编译资产后(由于任何 scss 文件中的更改),我注意到它可能工作或失败(出现该错误)。
我在每个 sass 文件中添加了一个 @debug "Compiling filename"
以了解编译顺序,并发现了一些对我来说很奇怪的东西。
它总是对每个 sass 文件编译两次,问题是有时它编译一次变量,因此在第二次编译 layout.scss
时会失败。
这是它工作时的样子:
这是失败时的样子:
如您所见,当它失败时,它会连续编译 layout.scss
文件两次,我的猜测是因为在第二次迭代时它不会导入其他文件,因此找不到变量如预期。
你知道这里可能出了什么问题吗?
解决方法
我确实发现了问题。
似乎在 Sprockets 4.0 上,这里定义了编译 scss 文件的方式:
# app/assets/config/manifest.js
//= link_tree ../images
//= link_directory ../stylesheets .css
这基本上会选择 stylesheets
文件夹中的任何 css/scss 文件进行编译。
因此,此问题的解决方案是更新清单以仅使用 link
到您想要作为入口点的唯一文件,还是仅保留 application.scss
文件文件夹级别,并将所有其他文件夹移动到子文件夹,这样它们就不会成为清单的目标。
我现在结束了这个,它有效:
// application.scss
@import "utils/normalize";
@import "variables/colors";
@import "variables/typography";
@import "variables/sizes";
@import "pages/layout";
所以 stylesheets/
中(至少在第一级深度)中唯一的 scss 文件是 application.scss
。
您可以在此处找到有关 sprockets upgrading docs 的更多信息:
您可能还会发现一些以前没有被编译为顶级目标的文件现在被编译了。例如,如果您现有的应用程序直接在 ./app/assets/javascripts 或 css/scss 文件 ./app/assets/stylesheets 中有任何 js 文件,Rails with Sprockets 4 现在会将它们编译为顶级目标。因为他们以前没有被这样对待,你可能不是故意的;如果它们是 .scss 部分引用要在其他文件中定义的变量,它甚至可能会导致错误消息看起来像 Undefined variable: $some_variable。