大家好,我是前端架构师,关注微信公众号【程序员大卫】免费领取前端精品资料。
一、背景
在前端开发中,模块化可以提高代码的可维护性和复用性。CSS 本身支持模块化,而 SASS 也提供了自己的模块化方案。
1. CSS 的模块化
CSS 通过 @import 指令来实现模块化,但它是运行时的,意味着浏览器在解析 CSS 时才会去加载和应用 @import 的内容。例如:
@import url("common.css");
CSS 的
@import指令支持 IE8+ 及主流浏览器,兼容性较好。
2. SASS 的模块化
SASS 的模块化是编译时的,它不能直接运行,而是需要先编译成 CSS 后才能被浏览器解析。SASS 提供了 @import 和 @use 两种模块化方式,其中 @use 是官方推荐的方式。
二、CSS 原生模块化
1. 示例演示
1.1 创建 index.html
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>CSS 模块化</title>
<link rel="stylesheet" href="./css/foo.css" />
</head>
<body>
Hello World
</body>
</html>
1.2 创建 CSS 文件
/* foo.css */
@import url("common.css");
/* common.css */
body {
font-size: 50px;
color: red;
}
最终,页面加载 foo.css 后,也会引入 common.css,使得 body 文字变大且变红。
三、SASS 的模块化
SASS 提供了两种实现模块化的方法:@import 和 @use(官方推荐)。
1. @import 方式
1.1 运行时模块化(类似 CSS 的 @import)
- 初始化项目并安装
sass依赖:
pnpm init
pnpm i sass -D
- 在
package.json中添加 SASS 编译命令:
{
"scripts": {
"sass": "sass --watch src/1.scss src/1.css --no-source-map"
}
}
- 创建 SASS 文件
src/1.scss:
@import url('abcdefg.css');
- 运行
pnpm sass,会生成src/1.css:
@import url('abcdefg.css');
由于
@import运行时不会检查文件是否存在,即使abcdefg.css不存在,编译也不会报错。
1.2 编译时模块化(SASS 内部模块化)
- 创建
src/common.scss:
$color: red;
* {
margin: 0;
padding: 0;
}
- 创建
src/foo.scss,并导入common.scss:
@import "common.scss";
body {
color: $color;
}
- 运行
pnpm sass后,生成的foo.css:
* {
margin: 0;
padding: 0;
}
body {
color: red;
}
2. @use 方式(官方推荐)
SASS 官方不推荐使用 @import,主要因为以下问题:
-
混淆:
@import既可以导入 CSS 文件,也可以导入 SASS 文件,容易造成歧义,影响代码可读性。 -
变量污染:
@import没有作用域隔离,不同文件的变量可能会互相覆盖。例如,如果引入@import 'common.scss'和@import 'var.scss',var.scss中的变量可能会覆盖common.scss中的变量。 -
缺乏私有性:所有导入的变量都是全局可见的,难以管理。例如,在
common.scss中定义变量$jjj: 1,但无法限制其仅在foo.scss内部使用,而是会暴露给所有导入的文件。
2.1 @use 的命名空间
将 foo.scss 中的 @import 改为 @use:
@use "common.scss";
body {
color: $color;
font-size: $size;
}
此时会报错 Error: Undefined variable.,因为 @use 会为每个模块添加命名空间。命名空间默认与文件名相同(如 common),修改代码如下即可编译成功:
@use "common.scss";
body {
color: common.$color;
font-size: common.$size;
}
2.2 自定义命名空间
可以使用 as 关键字自定义命名空间:
@use "common.scss" as theme;
body {
color: theme.$color;
}
2.3 取消命名空间(不推荐)
可以使用 as * 取消命名空间,使变量直接可用:
@use "common.scss" as *;
body {
color: $color;
}
但这种方式可能导致变量污染,不建议使用。
四、总结
| 模块化方式 | 作用 | 特点 |
|---|---|---|
CSS @import | 运行时加载 | 兼容性较好,但性能较低 |
SASS @import | 编译时加载 | 无作用域隔离,容易污染全局 |
SASS @use | 编译时加载 | 作用域清晰,官方推荐 |
在现代 SASS 项目中,建议优先使用 @use 进行模块化管理,以保持代码的清晰性和可维护性。