Sass模块化开发与引入方式
在 Sass 中,每个文件被视为一个模块,并且使用 Sass 编译器会将每个模块编译成独立的 CSS 文件。例如,main.scss
和 list.scss
分别会编译为 main.css
和 list.css
。
同时,Sass 采用了以 _
开头的命名规则,用于将一个文件作为模块引入到另一个文件中。当使用 @import
、@use
或 @forward
引入文件时,Sass 编译器会将这些文件编译为同一个 CSS 文件。
在 Sass 中每个文件都会认为一个模块,每个模块都被 sass-loader 编译成独立 css 文件。
例如 main.scss, _list.scss → main.css
Note: 所以'_'开头的 scss 文件一般用来定义变量,函数或者是 mixin 函数。
Sass 中引入别的文件的常用的几种方式
- @import
- @use
- @forward
- meta.load-css
# @import
使用方式是 @import ‘path/to/filename’,如果有~在 path 的前方,则认为这个文件是根据 webpack 的 alias,再去找对应的文件
如果被引入的文件有''的话,可以省略‘’,例如_filename.scss, 则通过@import 'filename'去引入。
import
在 Sass 中用于导入其他文件的样式。使用方式为 @import 'path/to/filename'
。如果在路径前添加了 ~
,则 Sass 编译器会将其视为 webpack 别名,并去查找对应文件。
如果被引入的文件的名称以 _
开头,则可以省略下划线。例如,对于 _filename.scss
文件,可以使用 @import 'filename'
进行引入。
然而,@import
是不被官方推荐的引入方式,因为它存在一些问题:
其一,@import 其实是 css 的标准;
其二,如果多次引入同样文件,会降低编译速度,造成样式冲突和覆盖,生成重复的样式;
其三,如果引入一个同名的函数,则会覆盖当前的函数
其四,无 scope 的概念,例如@import funciton1.scss, function2.scss,并在当前文件调用 abc 的函数,不知道 abc 函数式来自 function1 还是 function2
# @use
@use
是 Sass 官方推荐的模块引入方式,支持作用域的概念。
通过 @use
引入的模块具有独立的作用域,避免了样式冲突问题。
(但如果是用 node-sass 的方式,目前只支持@import)
// src/_corners.scss
$radius: 3px;
@mixin rounded {
border-radius: $radius;
}
// style.scss
@use 'src/corners';
.button {
@include corners.rounded;
padding: 5px + corners.$radius; // corners作为scope去调用,更符合前端人模块化的思维
}
@use
支持 with
操作符,用于修改被引入文件中变量的默认值
// _library.scss
$primary-color: #f8bbd0 !default;
$accent-color: #6a1b9a !default;
.button {
background-color: $primary-color;
border: 1px solid $accent-color;
border-radius: 3px;
}
// style.scss
@use 'library' with (
$primary-color: #fff,
$accent-color: #000
);
// 编译成css
.button {
background-color: #fff;
border: 1px solid #000;
border-radius: 3px;
}
# meta.load-css
这个跟@use
其实是非常相似的,不同的是要通过@include
的方式去引入,具有局部的概念
// dark-theme/_code.scss
$border-contrast: false !default;
code {
background-color: #6b717f;
color: #d2e1dd;
@if $border-contrast {
border-color: #dadbdf;
}
}
@use 'sass:meta';
body.dark {
@include meta.load-css(
'dark-theme/code',
$with: ('border-contrast': true)
); // 仅在body.dark下生效
}
// 编译成css
CSS OUTPUT body.dark code {
background-color: #6b717f;
color: #d2e1dd;
border-color: #dadbdf;
}
# @forward
作用就如词义—转发,当通过@use
的方法进入别的文件时,被引文件里的内容只能在当前文件中使用,第三个文件则使用不了,这时候@forward
就可以发挥作用了。
// src/_list.scss
@mixin list-reset {
margin: 0;
padding: 0;
list-style: none;
}
// bootstrap.scss
@forward 'src/list';
// styles.scss
@use 'bootstrap';
li {
@include bootstrap.list-reset;
}
// 编译成css
li {
margin: 0;
padding: 0;
list-style: none;
}
同时@forward
还提供一些方法 hide, as
默认@forward
全部变量方法都转发出去, 那么可以通过指定 hide 的方式去隐藏某些不让第三个文件去引用
而 as
的作用就重新指定名称,加前缀等方式,如 @forward "src/list" as abc-*;
则style.scss
就要用bootstrap.abc-list-reset
去引用对应的样式。