Sass 模块系统 #

模块系统概述 #

Sass 模块系统是现代 Sass 的核心特性,使用 @use@forward 实现代码的组织和复用。它解决了旧版 @import 的诸多问题。

@import vs @use #

特性 @import(旧) @use(新)
命名空间
私有成员 不支持 支持
重复加载 会多次加载 只加载一次
变量覆盖 全局覆盖 需显式配置
状态 已弃用 推荐

@use 基础 #

基本用法 #

scss
// _variables.scss
$primary-color: #3498db;
$secondary-color: #2ecc71;

// main.scss
@use 'variables';

.button {
  background-color: variables.$primary-color;
}

命名空间 #

@use 默认使用文件名作为命名空间:

scss
@use 'variables';
@use 'mixins';
@use 'functions';

.container {
  color: variables.$primary-color;
  @include mixins.flex-center;
  width: functions.calculate-width(100);
}

自定义命名空间 #

scss
@use 'variables' as v;
@use 'mixins' as m;
@use 'functions' as f;

.container {
  color: v.$primary-color;
  @include m.flex-center;
  width: f.calculate-width(100);
}

无命名空间 #

scss
@use 'variables' as *;

.container {
  color: $primary-color;  // 直接使用
}

加载索引文件 #

scss
// 自动加载 _index.scss
@use 'abstracts';
// 等同于 @use 'abstracts/index';

私有成员 #

定义私有成员 #

-_ 开头的成员是私有的:

scss
// _variables.scss
$-internal-color: red;  // 私有变量
$public-color: blue;    // 公开变量

@function -helper() {   // 私有函数
  @return red;
}

@function get-color() { // 公开函数
  @return $public-color;
}

私有成员不可访问 #

scss
@use 'variables';

.element {
  color: variables.$-internal-color;  // 错误!无法访问私有成员
  color: variables.$public-color;     // 正确
}

配置模块 #

使用 !default 定义可配置变量 #

scss
// _variables.scss
$primary-color: #3498db !default;
$secondary-color: #2ecc71 !default;
$border-radius: 4px !default;

使用 with 配置 #

scss
// main.scss
@use 'variables' with (
  $primary-color: #e74c3c,
  $secondary-color: #9b59b6,
  $border-radius: 8px
);

.button {
  background-color: variables.$primary-color;  // #e74c3c
}

多模块配置 #

scss
@use 'variables' with (
  $primary-color: #e74c3c
);

@use 'breakpoints' with (
  $md: 800px
);

@forward 转发 #

基本用法 #

@forward 用于创建模块索引,转发其他模块的内容:

scss
// abstracts/_index.scss
@forward 'variables';
@forward 'mixins';
@forward 'functions';

// main.scss
@use 'abstracts';

.element {
  color: abstracts.$primary-color;
  @include abstracts.flex-center;
}

添加前缀 #

scss
// abstracts/_index.scss
@forward 'variables' as var-*;
@forward 'mixins' as mx-*;

// main.scss
@use 'abstracts';

.element {
  color: abstracts.$var-primary-color;
  @include abstracts.mx-flex-center;
}

选择性转发 #

scss
// 只转发特定成员
@forward 'variables' show $primary-color, $secondary-color;

// 隐藏特定成员
@forward 'variables' hide $internal-var;

转发时配置 #

scss
// abstracts/_index.scss
@forward 'variables' with (
  $primary-color: #e74c3c !default
);

// main.scss
@use 'abstracts' with (
  $primary-color: #3498db
);

模块组织结构 #

7-1 模式 #

text
sass/
│
├── abstracts/
│   ├── _index.scss
│   ├── _variables.scss
│   ├── _mixins.scss
│   └── _functions.scss
│
├── base/
│   ├── _index.scss
│   ├── _reset.scss
│   ├── _typography.scss
│   └── _base.scss
│
├── components/
│   ├── _index.scss
│   ├── _buttons.scss
│   ├── _cards.scss
│   └── _forms.scss
│
├── layout/
│   ├── _index.scss
│   ├── _header.scss
│   ├── _footer.scss
│   └── _grid.scss
│
├── pages/
│   ├── _index.scss
│   ├── _home.scss
│   └── _about.scss
│
├── themes/
│   ├── _index.scss
│   └── _default.scss
│
└── main.scss

抽象层组织 #

scss
// abstracts/_variables.scss
$colors: (
  primary: #3498db,
  secondary: #2ecc71
) !default;

$spacing: (
  sm: 8px,
  md: 16px,
  lg: 24px
) !default;

// abstracts/_mixins.scss
@mixin flex-center {
  display: flex;
  justify-content: center;
  align-items: center;
}

// abstracts/_functions.scss
@function get-color($name) {
  @return map-get($colors, $name);
}

// abstracts/_index.scss
@forward 'variables';
@forward 'mixins';
@forward 'functions';

主文件结构 #

scss
// main.scss

// 1. 抽象层
@use 'abstracts' as *;

// 2. 基础样式
@use 'base';

// 3. 布局
@use 'layout';

// 4. 组件
@use 'components';

// 5. 页面
@use 'pages';

// 6. 主题
@use 'themes';

模块依赖 #

依赖其他模块 #

scss
// components/_buttons.scss
@use '../abstracts' as *;

.button {
  padding: map-get($spacing, md);
  background-color: map-get($colors, primary);
  
  @include flex-center;
}

循环依赖处理 #

scss
// 避免循环依赖
// a.scss 依赖 b.scss
// b.scss 依赖 a.scss

// 解决方案:提取公共部分到第三个模块
// _shared.scss
$common-var: value;

// a.scss
@use 'shared';

// b.scss
@use 'shared';

内置模块 #

sass:math #

scss
@use 'sass:math';

.element {
  width: math.div(100px, 2);  // 50px
  padding: math.round(4.6px);  // 5px
}

sass:color #

scss
@use 'sass:color';

.element {
  background-color: color.adjust(#3498db, $lightness: 20%);
  border-color: color.mix(red, blue, 50%);
}

sass:list #

scss
@use 'sass:list';

$list: 10px, 20px, 30px;

.element {
  margin: list.nth($list, 1);  // 10px
}

sass:map #

scss
@use 'sass:map';

$colors: (
  primary: #3498db,
  secondary: #2ecc71
);

.element {
  color: map.get($colors, primary);
}

sass:string #

scss
@use 'sass:string';

.element {
  content: string.to-upper-case("hello");  // "HELLO"
}

实际应用示例 #

设计系统 #

scss
// design-tokens/_colors.scss
$colors: (
  brand: (
    primary: #3498db,
    secondary: #2ecc71
  ),
  semantic: (
    success: #2ecc71,
    warning: #f39c12,
    danger: #e74c3c
  )
) !default;

// design-tokens/_spacing.scss
$spacing: (
  0: 0,
  1: 0.25rem,
  2: 0.5rem,
  3: 1rem,
  4: 1.5rem,
  5: 3rem
) !default;

// design-tokens/_index.scss
@forward 'colors';
@forward 'spacing';
@forward 'typography';
@forward 'breakpoints';

// main.scss
@use 'design-tokens' as tokens;

.element {
  color: map-get(tokens.$colors, brand, primary);
  padding: map-get(tokens.$spacing, 3);
}

组件库 #

scss
// components/_button.scss
@use '../abstracts' as *;

.button {
  display: inline-block;
  padding: map-get($spacing, 2) map-get($spacing, 3);
  border: none;
  border-radius: $border-radius;
  cursor: pointer;
  
  &--primary {
    background-color: map-get($colors, primary);
    color: white;
  }
  
  &--secondary {
    background-color: map-get($colors, secondary);
    color: white;
  }
}

// components/_index.scss
@forward 'button';
@forward 'card';
@forward 'form';

// main.scss
@use 'components';

从 @import 迁移 #

迁移步骤 #

  1. @import 改为 @use
  2. 添加命名空间
  3. 使用 @forward 创建索引

迁移前 #

scss
@import 'variables';
@import 'mixins';

.button {
  color: $primary-color;
  @include flex-center;
}

迁移后 #

scss
@use 'variables';
@use 'mixins';

.button {
  color: variables.$primary-color;
  @include mixins.flex-center;
}

自动迁移工具 #

bash
# 安装迁移工具
npm install -g sass-migrator

# 执行迁移
sass-migrator module --migrate-deps styles/

最佳实践 #

1. 使用索引文件 #

scss
// 好:使用索引文件统一导出
@use 'abstracts';

// 不好:逐个导入
@use 'abstracts/variables';
@use 'abstracts/mixins';
@use 'abstracts/functions';

2. 合理使用命名空间 #

scss
// 好:简短清晰的命名空间
@use 'abstracts' as a;

// 不好:无命名空间(可能导致冲突)
@use 'abstracts' as *;

3. 私有成员保护 #

scss
// 好:使用私有前缀保护内部实现
$-internal-var: value;
@function -helper() { }

// 不好:所有成员都公开
$internal-var: value;
@function helper() { }

4. 模块职责单一 #

scss
// 好:每个文件职责单一
// _variables.scss - 只定义变量
// _mixins.scss - 只定义混合宏

// 不好:一个文件包含所有
// _utils.scss - 变量、混合宏、函数混在一起

下一步 #

掌握了模块系统后,继续学习 最佳实践,了解 Sass 项目的开发规范!

最后更新:2026-03-28