导入 @import
约 1920 字大约 6 分钟
2025-04-05
在 Sass 中,@import
是一个用于将多个 Sass/SCSS 文件合并编译为单个 CSS 文件的关键规则。它允许你将代码拆分为模块化的部分,并通过导入机制组合在一起。以下是关于 @import
的详细说明:
一、基本介绍
- 省略后缀名: 文件扩展名(
.scss
或.sass
)可以省略。 - 局部文件省略
_
: 可以导入局部文件(以_
开头的文件),导入时可以省略_
。 - 路径格式: 路径可以是相对路径、绝对路径(不推荐)或通过配置的加载路径(load path)。
- 重复导入: 重复多次导入同一个文件不会重复编译。
- 按照导入顺序编译:导入的文件会按照导入顺序编译,确保正确的依赖关系。
- 支持嵌套: 可以嵌套导入,导入的内容会作用在嵌套的上下文中。
- 条件导入: 可以使用条件语句(
@if
、@else
)来动态选择导入的文件。 - 支持导入 css: 支持导入 css 文件,但是导入的文件会被解析为 CSS 文件,因此不建议直接导入 CSS 文件。
- 降级: 当找不到对应的
.scss
或.sass
文件时,会尝试降级为 CSS 文件。 - 优先级规则:如果同时存在同名
.scss
和.css
文件(如_styles.scss
和styles.css
),Sass 优先导入.scss
文件。 - 私有文件:以
-
或_
开头的成员无法被外部访问。
二、用法介绍
1、基础导入
// 导入另一个 Sass/SCSS 文件
@import "variables";
@import "mixins";
@import "components/button";
2、导入局部文件(Partials)
Sass 使用 以下划线开头的文件名(如 _variables.scss
)表示“局部文件”。这类文件不会被直接编译为 CSS,而是通过 @import
引入到其他文件中。
@import "variables"; // 实际导入的是 _variables.scss
3、一次导入多个文件
@import "header", "footer", "utils/mixins";
4、嵌套导入
@import
可以嵌套在代码块内,此时导入的内容会作用在嵌套的上下文中:
.container {
@import "grid";
}
编译后,grid.scss
中的所有样式会被包裹在 .container
选择器内。
5、条件导入
@if $is-desktop {
@import "desktop";
} @else {
@import "mobile";
}
6、导入 CSS 文件
- 可以直接导入 CSS 文件,但不推荐这样做,因为 Sass 主要用于编写样式,而不是直接使用 CSS。
@import "normalize"; // 不推荐
二、路径解析
1、相对路径
- 使用
./
表示当前目录,../
表示上级目录。 - 相对路径通常用于导入同一项目中的文件。
@import "./variables"; // 相对于当前文件
@import "../utils/mixins"; // 相对于当前文件的上级目录
2、绝对路径 不推荐
从系统根目录开始,例如
/src/styles/variables.scss
。不推荐使用绝对路径,因为在不同环境下可能会导致路径错误。
@import "/src/styles/variables"; // 绝对路径
3、加载路径(Load Paths)
- 通过命令行或配置文件指定额外的搜索路径。
- 可以通过
--load-path
或sassOptions.loadPaths
配置。 通过命令行或构建工具添加额外搜索路径,避免冗长的相对路径。
命令行配置
sass --load-path=src/styles --load-path=node_modules src/main.scss dist/main.css
Webpack 配置(sass-loader)
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.scss$/,
use: [
"sass-loader",
{
loader: "sass-loader",
options: {
sassOptions: {
loadPaths: ["src/styles", "node_modules"],
},
},
},
],
},
],
},
};
4、别名(Aliases)简化路径
- 通过构建工具(如 Webpack)或 Sass 配置为常用路径设置别名。
- 简化路径,提高开发效率。
// webpack.config.js
module.exports = {
resolve: {
alias: {
"@styles": path.resolve(__dirname, "src/styles"),
},
},
};
// Sass 中使用别名
@import "@styles/variables"; // 指向 src/styles/_variables.scss
5、模块导入
有时候我们遇到@import "moudle/variables"
这样的格式,moudle
可能代表一个模块,可能代表一个路径。例如一下文件结构:
src
styles
main.scss
components
\_button.scss
components
\_button.scss
node_modules
bootstrap
scss
\_button.scss
在以上结构中,我们在src/styles
目录下的 main.scss
中引入 @import "moudle/file"
可能代表以下几种情况:
moudle
可能是一个模块名,例如@import "bootstrap/scss/_button"
。这种情况下,Sass 会在node_modules
目录下查找bootstrap
模块,并导入其局部文件_button.scss
。moudle
可能是同级别的其他文件的一个路径,例如@import "components/button"
。这种情况下,Sass 会在src/styles
目录下查找components/_button.scss
文件,并导入它。moudle
可能是一个项目目录下的路径,例如@import "components/button"
。这种情况下,Sass 会直接从系统根目录下查找src/components/_button.scss
文件,并导入它。
三、与 CSS 原生 @import
的区别
- Sass 的
@import
:在编译阶段合并代码,最终生成一个 CSS 文件。 - CSS 的
@import
:在浏览器中发起额外的 HTTP 请求,影响性能。
如果 Sass 遇到以下情况,会将其视为原生 CSS 的 @import
:
- 导入路径以
.css
结尾。 - 路径是
http://
或url()
。 - 包含媒体查询(media queries)。
@import "theme.css"; // 原生的 CSS @import
@import "landscape" screen; // 包含媒体查询,原生的 CSS @import
四、识别失效,自动降级
提示
@import
在以下情况退化为原生 CSS 导入:
- 路径指向
.css
文件 - 包含网络协议(
http://
、https://
) - 使用
url()
语法 - 包含媒体查询或条件
- 动态路径(插值或变量)
- 找不到对应的 Sass 文件
以下场景可能导致 scss
降级识别为 css
:
1、导入 .css
文件
如果导入的文件扩展名是 .css
,Sass 会直接生成 CSS 原生 @import
:
@import "reset.css";
编译结果
@import url("reset.css");
2、导入路径包含 http://
或 https://
使用网络协议路径时,Sass 会保留为原生导入:
@import "https://example.com/styles.css";
编译结果
@import url("https://example.com/styles.css");
3、使用 url()
语法
显式使用 url()
包裹路径时,Sass 会按 CSS 处理:
@import url("theme.css");
编译结果
@import url("theme.css");
4、包含媒体查询或条件
在 @import
后添加媒体查询(如 screen
、print
等)时,Sass 会保留为原生导入:
@import "print-styles.css" print;
编译结果
@import url("print-styles.css") print;
5、动态路径(插值或变量)
如果路径包含插值(#{}
)或变量,且无法在编译时解析为有效的静态路径,Sass 会退化为原生导入:
$theme: "dark";
@import "themes/#{$theme}/styles";
编译结果(假设没有对应的 Sass 文件):
@import url("themes/dark/styles.css");
6、找不到对应的 Sass 文件
如果 Sass 找不到同名的 .scss
或 .sass
文件(包括部分文件),会退化为原生导入:
@import "nonexistent-file";
编译结果(假设不存在 _nonexistent-file.scss
):
@import url("nonexistent-file.css");
7、强制原生导入的 !optional
标志
使用 !optional
标志且文件不存在时,Sass 会静默忽略,不生成任何导入:
@import "missing-file.css" !optional;
编译结果
/* 无输出 */
五、注意事项
- 逐步弃用:Dart Sass 已计划弃用
@import
,推荐使用@use
和@forward
(需配合模块系统@use
更安全,避免全局作用域污染)。 - 变量覆盖:通过
@import
导入的变量和混入(mixins)是全局的,可能导致命名冲突。 - 循环导入:避免文件之间相互导入,可能导致编译错误。
- 性能影响:原生 CSS
@import
会增加 HTTP 请求,影响性能,建议合并文件或使用构建工具处理。 - 跨操作系统路径处理:
- 统一使用
/
:Sass 在 Windows 和 Unix 系统中均支持/
作为路径分隔符。 - 避免反斜杠
\
:可能导致解析失败。
- 统一使用
六、替代方案:@use
和模块系统
在新版 Sass 中,建议使用 @use
替代 @import
,它通过命名空间隔离变量,避免全局污染:
@use "variables"; // 变量通过命名空间访问:variables.$color
@use "mixins" as m; // 自定义命名空间:m.mixin()
更新日志
e7112
-1于