如何使用@use 在多个页面上使用 SASS $variable?

Mic*_*eno 9 css sass

我正在尝试使用在另一个部分内部的一个部分上声明的变量,这两个部分都将使用@use 加载到 main.scss 文件中,然后将其编译为 css。

这是设置:

样式文件

@use './global';
@use './header';
Run Code Online (Sandbox Code Playgroud)

_global.scss

$black: #262626;
Run Code Online (Sandbox Code Playgroud)

_header.scss

header {
  color: $black
}
Run Code Online (Sandbox Code Playgroud)

当我运行尝试编译 style.css 时,出现此错误:

C:\xampp\htdocs\Site\styles>sass style.scss:style.css
Error: Undefined variable.
  ?
3 ?   color: $black;
  ?          ^^^^^^
  ?
  _header.scss 3:10  @use
  style.scss 2:1     root stylesheet
Run Code Online (Sandbox Code Playgroud)

如果我在主 style.scss 中使用 @import 而不是 @use,它会工作正常,但是 Sass 的开发人员建议不要使用 @import,因为它最终将被弃用。

他们说改用@use,@use 比@import 有很多优点,其中之一是@use 的所有实例可以同时加载。我认为这是导致问题的原因,因为 _global.scss 无法在依赖于 _global.scss 中定义的 $black 的页面之前加载,因此这些页面加载时没有定义 $black。

有任何想法吗?

Coo*_*gan 10

从Sass Lang 文档中@use:

使用@use 加载的成员(变量、函数和mixin)仅在加载它们的样式表中可见

import按照 JavaScript 中的思路思考,而不是使用 Sass@import语法的传统全局范围。

我认为您可能会尝试执行以下操作:

global.scss

$black: #000;
Run Code Online (Sandbox Code Playgroud)

头文件.scss

@use "global";

.header {
  color: global.$black;
}
Run Code Online (Sandbox Code Playgroud)

按钮.scss

@use "global";

.button {
  color: global.$black;
}
Run Code Online (Sandbox Code Playgroud)

索引.scss

@use './button';
@use './header';
Run Code Online (Sandbox Code Playgroud)

这可能比您传统上习惯使用 Sass 更冗长/麻烦,但从长远来看,它肯定有巨大的好处 - 特别是如果您是框架或库作者,甚至使用现有的自己的修改在上面。

许多开发人员(包括我自己)不得不处理的 Sass 的一个大痛点是在根范围内声明的变量,实际上,所有Sass 函数都是全局可用的。虽然这有时很方便,但在集成外部编写的库或在具有许多分布式团队的大公司工作时,它也会导致大量冲突。

例如:如果我使用 Bootstrap 作为我网站风格的基础,并且我加载了一个额外的库来定义它自己的gradient-bgmixin(也在 TWBS 中定义),哪个 mixin 是正确的使用?加载顺序对此有影响,您可能看不到任何问题,但您也可能会看到预期输出中存在巨大差异,这现在需要您深入研究这些库以了解发生了什么。

该@use规则通过确保模块成员(变量、函数和 mixin)只能在加载它们的样式表内访问来解决这个问题。它还具有一个额外的好处,即允许您进一步简化成员名称——因为它们被限定在一个命名空间(模块 URL 的最后一个组件)中,您可以继续定义$padding或@mixin flex {}。

组织

最终,这可以帮助您在逻辑上将自己的代码组织成一个结构,从而更容易维护您的代码(对于您的同事和您自己)。明确代码的作用并没有错,特别是因为当您计划将来进行更新时,您希望它是可靠和可预测的。

就我个人而言,我非常喜欢一种与以下类似的结构:

styles
|-- global
|    |-- functions.scss
|    |-- spacing.scss
|    |-- typography.scss
|    |-- ...etc...
|-- component
|    |-- button.scss
|    |-- header.scss
|    |-- ...etc...
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您的代码将类似于:

按钮.scss

$black: #000;
Run Code Online (Sandbox Code Playgroud)

全局命名空间

当然,这完全取决于个人喜好,我知道有些人可能不是新命名空间的粉丝。这可以有所缓解,或者完全忽略。

和 @use

使用新的 Sass 模块系统时,使用@use. 但是,您可以使用@use "path/to/file" as *;语法加载没有命名空间的模块。这将允许您直接访问成员而无需<namespace>.<member>语法。

和 @import

如果这仍然不适合您的需求,您当然可以@import在可预见的未来继续使用该规则。该小组打算支持@import,直到围绕2022十月一段时间。此时,您始终可以将您的 Sass 版本固定到支持@import.

  • 与进口相比,这似乎效率低下。为什么我必须将 Use 设置为“global”;如果我已经将其加载到 main.scss 的顶部,则在每个模块的顶部?此外,为什么一旦加载“全局”名称空间就必须指定名称空间?对于导入,我所要做的就是导入“全局”;在我的 main.scss 的顶部,然后所有后续导入都可以访问 _global.scss 中定义的变量,而使用 Use 我必须在每个其他部分的顶部加载 _global.scss,然后另外指定这些部分中的名称空间..导入在这方面似乎更优越。 (2认同)
  • 我明白你的意思。我已经用更多信息更新了我的答案,以解决您的疑虑! (2认同)