Раньше в Sass был только @import, который просто копировал содержимое одного файла в другой. Это создавало проблемы: глобальное загрязнение, конфликты имён, дублирование кода.@use и @forward появились несколько лет назад, но только сейчас, с приближением выхода Dart Sass 3.0.0, @import официально объявлен устаревшим и будет полностью удалён. В связи с этим стоит разобраться с модульной системой, если вы её до сих пор обходили стороной.

1. @use — подключение модуля

@use загружает файл (модуль) и делает его содержимое доступным в текущем файле, но в изолированном пространстве имён. Это главное отличие от @import.

@use 'путь/файл'; 

По умолчанию все переменные, миксины и функции из загруженного файла становятся доступны через пространство имён, равное последней части пути (без подчёркивания и расширения).

Пример:

$primary: blue;
$secondary: gray; 

Подключаем в body/header.scss:

@use '../helpers/colors';

.button {
  color: colors.$primary; //обращение через пространство имён "colors" 
}

Важно: пространство имён по умолчанию берётся из названия файла.

2. Изменение пространства имён (as)

Можно задать своё имя для модуля, чтобы сократить или уточнить контекст:

@use 'helpers/colors' as myColors;

.button {
  color: myColors.$primary; //обращение через "myColors"
}

Пространства имён в Sass — это идентификаторы, они подчиняются тем же правилам, что и имена переменных:

✅ МОЖНО:

  • буквы a–z, A–Z

  • цифры 0–9 (но не в начале)

  • camelCase (myColors)

  • PascalCase (MyColors)

❌ НЕЛЬЗЯ:

  • дефис (-)

  • пробелы

  • спецсимволы (!@#$%^&*)

  • начинаться с цифры

3. Встроенные модули (math, list, map, color, string)

Sass предоставляет встроенные модули, которые подключаются через @use с префиксом sass::

@use 'sass:math';
@use 'sass:list';
@use 'sass:map';
@use 'sass:color';
@use 'sass:string';

Примеры:

$width: math.div(100%, 3); //деление
$len: list.length($my-list); //длина списка
$color: color.adjust(#336699, $lightness: 20%);
$index: string.index($string, 'sub'); 

Важно: встроенные модули нужно подключать в каждом файле, где используются их функции. Они не наследуются через другие импорты.

4. Использование миксинов и функций из модулей

Миксины и функции, определённые в пользовательских файлах, тоже доступны через пространство имён:

// helpers/_mixins.scss
@mixin flex-center {
  display: flex;
  align-items: center;
  justify-content: center;
}
// components/_card.scss
@use '../helpers/mixins';

.card {
  @include mixins.flex-center;
}

Если нужно импортировать несколько модулей в одном файле, делаем это явно:

@use '../helpers/colors';
@use '../helpers/variables' as var;
@use '../helpers/mixins'; 

5. Организация файлов

Каждый SCSS-файл сам отвечает за свои зависимости. В начале файла перечисляются все необходимые модули с помощью @use. Это обеспечивает полную прозрачность и упрощает рефакторинг.

Рекомендуемая структура папок:

scss/
  helpers/
    _colors.scss
    _variables.scss
    _mixins.scss
  components/
    _button.scss
    _card.scss
  pages/
    _about-page.scss
  template.scss 

Пример components/_button.scss:

@use '../helpers/colors' as myColors;
@use '../helpers/variables';
@use '../helpers/mixins';

.button {
  background-color: myColors.$primary;
  padding: variables.$spacing-md;
  @include mixins.border-radius;
} 

6. Преимущества подхода с пространством имён

  • Явность — сразу видно, из какого модуля взята переменная/миксин.

  • Отсутствие конфликтов — даже если в разных модулях есть одинаковые имена, они не пересекаются.

  • Лёгкий рефакторинг — можно менять один модуль, не боясь сломать другие.

  • Поддержка IDE — автодополнение работает лучше, так как пространства имён известны.

  • Масштабируемость — код остаётся понятным даже в больших проектах.

7. Важные замечания

@use работает только в начале файла (до любых правил).

  • Один и тот же модуль можно использовать в нескольких файлах, каждый раз подключая его явно.

  • Встроенные модули не нужно копировать в проект — они уже есть в Sass. Их нужно явно подключать в необходимом файле:

@use '../helpers/colors' as myColors;
@use '../helpers/variables';
@use '../helpers/mixins';
@use 'sass:list';

.button {
  background-color: myColors.$primary;
  padding: variables.$spacing-md;
  @include mixins.border-radius;
  $len: list.length($my-list; //длина списка
} 

8. @use ... with ()

@use ... with () — это механизм конфигурации модулей в Sass. Он позволяет передавать значения в модуль при его импорте, переопределяя переменные, которые помечены как !default.

8.1 Как это работает:

В модуле объявляются переменные с !default

// helpers/_theme.scss

$bg-color: #ffffff !default; //значение по умолчанию
$text-color: #333333 !default; //можно переопределить
$spacing-unit: 8px !default; //можно переопределить
$border-radius: 4px !default; //можно переопределить 

!default означает: «используй это значение, если никто не передал своё»:

  • Если значение НЕ БЫЛО задано до импорта — используется то, что после !default

  • Если значение УЖЕ БЫЛО задано — используется заданное, а значение после !default игнорируется

Пример, когда значение было задано ДО импорта:

// helpers/_theme.scss

$bg-color: #ffffff !default;  //будет белый, если никто не задал другой
// pages/about-page.scss$bg-color: #000000;  //задали чёрный ДО импорта

@use 'helpers/theme';

body {
  background: theme.$bg-color;  //будет #000000
}

8.2 При импорте передаём новые значения через with:

// pages/dark-theme.scss
@use '../helpers/theme' with (
  $bg-color: #1a1a1a,
  $text-color: #f0f0f0,
  $spacing-unit: 12px
);

body {
  background: theme.$bg-color; //будет #1a1a1a
  color: theme.$text-color; //будет #f0f0f0
  padding: theme.$spacing-unit; //будет 12px
  border-radius: theme.$border-radius; // будет 4px (осталось по умолчанию)
} 

Выходит, что с помощью @use ... with(), мы также переопределяем переменные, только вместо "ДО импорта", мы прописываем с помощью with в скобках самого импорта.

Таким образом, у нас есть два способа переопределить переменные в конкретном файле

  1. Сделать это до конкретного импорта, а лучше вышел всех импортов в файле .scss

  2. Переопределить переменную из определенного импорта, используя with()

8.3 Примечание

  1. Многие Sass-библиотеки используют !default для настройки своих стилей. Их также можно переопределить двумя способами, указанными выше (если такое требуется).

  2. Для одного и того же модуля директива with() работает только при первом импорте. Все последующие @use ... with() для этого же модуля будут проигнорированы:

// Правильно
@use 'helpers/theme' with (
  $bg-color: #000
);

// Бесполезно (повторный импорт игнорирует with)
@use 'helpers/theme' with (
  $bg-color: #f00  //НЕ СРАБОТАЕТ!
);

Можно применять @use... with() для каждого импорта (но не для одного и того же повторно):

// helpers/colors

// Правильно
@use 'helpers/colors' with (
  $primary: red,
  $secondary: lightgray
);

// helpers/spacing

// Правильно
@use 'helpers/spacing' with (
  $padding: 24px,
  $margin: 12px
);

9. @forward — проброс модуля

@forward — это директива, которая передаёт содержимое подключённых файлов дальше, но сама не даёт к ним доступ в текущем файле. Она используется для создания единой точки входа (публичного API) из нескольких модулей.

9.1 Что делает @forward?

@forward полезен тем, что его можно использовать в одном scss файле, который можно импортировать в scss файлах и при этом не прописывать несколько штук импортов в каждом файле.

Пример с @forward:

Создаем scss файл, допустим _core.scss, и прописываем в нем ссылки, с помощью @forward, на scss файлы, которые являются для нас глобальными (переменные, цвета, миксины, шрифты, базовые стили и прочее)

// core.scss

@forward "helpers/colors";
@forward "helpers/variables";
@forward "base/fonts";
@forward "helpers/fonts-variables";
@forward "helpers/extend";
@forward "base/reset";
@forward "base/reboot";
@forward "base/base";
@forward "base/new-system";

И дальше добавляем только один импорт в scss файлах:

//./pages/about-page.scss

@use "../core.scss";

Плюс в том, что вместо, например, 9 импортов, мы будем использовать только один "core".

НО минус такого подхода состоит в том, что при использовании пространства имен (неймспейс), мы не сможем точно определить из какого scss файла нужная нам переменная, так как все неймспейсы будут равны имени одного файла (c @forward) или же назначенному нами имени (через as). Итог с @forward:

// ./pages/about-page.scss

@use "../core.scss"; //или @use "../core.scss" as core;

.button {
  color: core.$blue;
  border-radius: core.$border-radius-medium;
  @include core.flex-center;
}

Без @forward удобнее тем, что мы сразу можем определить из какого файла, нужный нам стиль, как было описано выше. Но вот еще пример:

// ./pages/about-page.scss

@use '../helpers/colors';
@use '../helpers/variables';
@use '../helpers/mixins';

.button {
  color: color.$blue;
  border-radius: variables.$border-radius-medium;
  @include mixins.flex-center;
} 

9.2 Важный нюанс

Как уже говорилось, @forward только пробрасывает содержимое дальше, но сам файл, в котором написаны @forward, не получает доступа к этим переменным и миксинам. Если внутри _core.scss понадобится использовать что-то из проброшенных файлов, нужно добавить отдельный @use.

// _core.scss

@forward 'helpers/colors; //проброс наружу
@use 'helpers/colors' as c; //для использования внутри

body {
  background: c.$bg-color; //работает благодаря @use
} 

9.3 Пространство имён при использовании @forward

При импорте файла-сборщика через @use пространство имён определяется так же, как и для обычного модуля.

9.4 Выборочный проброс (show / hide)

С помощью show и hide можно ограничить, что именно пробрасывается из модуля:

  • show — пробросить только перечисленные имена

  • hide — пробросить всё, кроме перечисленных

// helpers/_index.scss

@forward 'colors' show $primary, $secondary; //только эти переменные
@forward 'mixins' hide private-mixin; //все, кроме private-mixin

9.5 Конфигурация через with() при пробросе

Если пробрасываемый файл содержит переменные с !default, их можно переопределить прямо в @forward с помощью with():

// helpers/_theme.scss

$bg-color: #fff !default;
$text-color: #000 !default;

// helpers/_index.scss

@forward 'theme' with (
  $bg-color: #f0f0f0,
  $text-color: #222
);

10. Как организовывать зависимости между модулями

В модульной системе Sass каждый файл изолирован и должен явно указывать, откуда он берёт переменные, миксины и функции. Это касается и случаев, когда один ваш модуль (например, variables.scss) использует переменные из другого модуля (colors.scss).

Пример: variables.scss зависит от colors.scss

// _core.scss

@forward 'helpers/colors';
@forward 'helpers/variables';
@forward 'helpers/mixins';

Внутри _variables.scss по-прежнему нужно писать:

//variables.scss

@use 'colors; //явная зависимость
// ...

Почему это правильно:

  • Явность – сразу видно, от каких модулей зависит файл.

  • Надёжность – при переносе файла в другое место зависимости не теряются.

  • Поддержка IDE – автодополнение работает чётко.

  • Рефакторинг – легко найти все места, использующие конкретный модуль.

11. Краткие итоги

  • Явность важнее краткости – каждый файл сам импортирует нужные модули через @use. Это делает зависимости прозрачными.

  • Пространство имён обязательно – обращайся к переменным/миксинам через имя модуля (или алиас). Никакого глобального доступа.

  • Имена модулей – только буквы, цифры (не в начале). Дефисы и спецсимволы запрещены.

  • Встроенные модули (sass:math, sass:list и др.) подключаются там, где используются. Они не наследуются.

  • Конфигурация через !default и with() – позволяет гибко настраивать модули, переопределяя значения по умолчанию. with() работает только при первом импорте.

  • @forward для сборки – удобен для создания единой точки входа, но скрывает источник переменных. Используй осознанно.

  • show / hide в @forward – позволяют точечно контролировать, что попадает в публичное API.

  • Зависимости внутри модулей – даже если файл входит в сборщик, внутри него нужно явно писать @use для других модулей.

  • Повторные импорты – норма. Даже если один модуль нужен в ста файлах, в каждом пишем @use. Это плата за надёжность.

  • Рефакторинг становится безопасным – изменения в одном модуле не ломают другие, если их имена не конфликтуют.

12. Глобальный подход (который не стоит использовать, но о котором стоит просто знать)

В документации я описал @use ... as для создания псевдонима модуля. Но существует ещё один вариант: @use ... as * .

@use 'helpers/colors' as *;

as * импортирует модуль в глобальное пространство имён. Переменные, миксины и функции становятся доступны без префикса — как в старом добром import.

  • Возвращает те самые проблемы, от которых уходили — конфликты имён, глобальное загрязнение, неявные зависимости.

  • Ломает прозрачность кода — глядя на $primary, невозможно понять, из какого модуля эта переменная.

  • Рефакторинг становится опасным — удаление или переименование модуля может сломать код в неочевидных местах.

  • Сам Dart Sass не рекомендует этот подход — он оставлен только для плавного перехода с import, но не для использования в новой кодовой базе.

Итог: as * — это лазейка из прошлого. Если вы пишете код с нуля или мигрируете проект осознанно, используйте обычные пространства имён. Явность важнее краткости.