- PVSM.RU - https://www.pvsm.ru -
Раньше в Sass был только @import, который просто копировал содержимое одного файла в другой. Это создавало проблемы: глобальное загрязнение, конфликты имён, дубл��рование кода. Начиная с Dart Sass (современная версия), @import объявлен устаревшим и будет полностью удалён в версии 3.0.0. Вместо него введена модульная система с правилами @use.
@use загружает файл (модуль) и делает его содержимое доступным в текущем файле, но в изолированном пространстве имён. Это главное отличие от @import.
@use 'путь/файл';
По умолчанию все переменные, миксины и функции из загруженного файла становятся доступны через пространство имён, равное последней части пути (без подчёркивания и расширения).
Пример:
Файл helpers/_colors.scss:
$primary: blue;
$secondary: gray;
Подключаем в body/header.scss:
@use '../helpers/colors';
.button {
color: colors.$primary; // обращение через пространство имён "colors"
}
Важно: пространство имён по умолчанию берётся из названия файла.
Можно задать своё имя для модуля, чтобы сократить или уточнить контекст:
@use 'helpers/colors' as myColors;
.button {
color: myColors.$primary; // обращение через "myColors"
}
Пространства имён в Sass — это идентификаторы, они подчиняются тем же правилам, что и имена переменных:
✅: МОЖНО:
буквы a–z, A–Z
цифры 0–9 (но не в начале)
camelCase (myColors)
PascalCase (MyColors)
❌: НЕЛЬЗЯ:
дефис (-)
пробелы
спецсимволы (!@#$%^&*)
начинаться с цифры
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');
Важно: встроенные модули нужно подключать в каждом файле, где используются их функции. Они не наследуются через другие импорты.
Миксины и функции, определённые в пользовательских файлах, тоже доступны через пространство имён:
// 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';
Каждый 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;
}
Явность — сразу видно, из какого модуля взята переменная/миксин.
Отсутствие конфликтов — даже если в разных модулях есть одинаковые имена, они не пересекаются.
Лёгкий рефакторинг — можно менять один модуль, не боясь сломать другие.
Поддержка IDE — автодополнение работает лучше, так как пространства имён известны.
Масштабируемость — код остаётся понятным даже в больших проектах.
@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); // длина списка
}
@use [1] ... with () — это механизм конфигурации модулей в Sass. Он позволяет передавать значения в модуль при его импорте, переопределяя переменные, которые помечены как !default.
В модуле объявляются переменные с !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; // будет белый, если никто не задал другой
$bg-color: #000000; // задали чёрный ДО импорта
@use 'helpers/theme';
body {
background: theme.$bg-color; // будет #000000
}
// 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 [1] ... with(), мы также переопределяем переменные, только вместо "ДО импорта", мы прописываем с помощью with в скобках самого импорта.
Таким образом, у нас есть два способа переопределить переменные в конкретном файле
Сделать это до конкретного импорта, а лучше вышел всех импортов в файле .scss
Переопределить переменную из определенного импорта, используя with()
Многие Sass-библиотеки используют !default для настройки своих стилей. Их также можно переопределить двумя способами, указанными выше (если такое требуется).
Для одного и того же модуля директива with() работает только при первом импорте. Все последующие @use [1] ... with() для этого же модуля будут проигнорированы:
// Правильно
@use 'helpers/theme' with (
$bg-color: #000
);
// Бесполезно (повторный импорт игнорирует with)
@use 'helpers/theme' with (
$bg-color: #f00 // НЕ СРАБОТАЕТ!
);
Можно применять @use [1]... with() для каждого импорта (если требуется):
// helpers/colors
// Правильно
@use 'helpers/colors' with (
$primary: red,
$secondary: lightgray
);
// helpers/spacing
// Правильно
@use 'helpers/spacing' with (
$padding: 24px,
$margin: 12px
);
@forward [2] — это директива, которая передаёт содержимое подключённых файлов дальше, но сама не даёт к ним доступ в текущем файле. Она используется для создания единой точки входа (публичного API) из нескольких модулей.
@forward [2] полезен тем, что его можно использовать в одном scss файле, который можно импортировать в scss файлах и при этом не прописывать несколько штук импортов в каждом файле.
Пример с @forward [2]:
Создаем scss файл, допустим _core.scss, и прописываем в нем ссылки, с помощью @forward [2], на 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 [2]) или же назначенному нами имени (через as). Итог с @forward [2]:
// ./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 [2] удобнее тем, что мы сразу можем определить из какого файла, нужный нам стиль, как было описано выше. Но вот еще пример:
// ./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;
}
Как уже говорилось, @forward [2] только пробрасывает содержимое дальше, но сам файл, в котором написаны @forward [2], не получает доступа к этим переменным и миксинам. Если внутри _core.scss понадобится использовать что-то из проброшенных файлов, нужно добавить отдельный @use [1].
// _core.scss
@forward 'helpers/colors'; // проброс наружу
@use 'helpers/colors' as c; // для использования внутри
body {
background: c.$bg-color; // работает благодаря @use
}
При импорте файла-сборщика через @use [1] пространство имён определяется так же, как и для обычного модуля.
С помощью show и hide можно ограничить, что именно пробрасывается из модуля:
show — пробросить только перечисленные имена
hide — пробросить всё, кроме перечисленных
// helpers/_index.scss
@forward 'colors' show $primary, $secondary; // только эти переменные
@forward 'mixins' hide private-mixin; // все, кроме private-mixin
Если пробрасываемый файл содержит переменные с !default, их можно переопределить прямо в @forward [2] с помощью with():
// helpers/_theme.scss
$bg-color: #fff !default;
$text-color: #000 !default;
// helpers/_index.scss
@forward 'theme' with (
$bg-color: #f0f0f0,
$text-color: #222
);
В модульной системе 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 – автодополнение работает чётко.
Рефакторинг – легко найти все места, использующие конкретный модуль.
Явность важнее краткости – каждый файл сам импортирует нужные модули через @use [1]. Это делает зависимости прозрачными.
Пространство имён обязательно – обращайся к переменным/миксинам через имя модуля (или алиас). Никакого глобального доступа.
Имена модулей – только буквы, цифры (не в начале) и подчёркивание. Дефисы и спецсимволы запрещены.
Встроенные модули (sass:math, sass:list и др.) подключаются там, где используются. Они не наследуются.
Конфигурация через !default и with() – позволяет гибко настраивать модули, переопределяя значения по умолчанию. with() работает только при первом импорте.
@forward [2] для сборки – удобен для создания единой точки входа, но скрывает источник переменных. Используй осознанно.
show / hide в @forward [2] – позволяют точечно контролировать, что попадает в публичное API.
Зависимости внутри модулей – даже если файл входит в сборщик, внутри него нужно явно писать @use [1] для других модулей.
Повторные импорты – норма. Даже если один модуль нужен в ста файлах, в каждом пишем @use [1]. Это плата за надёжность.
Рефакторинг становится безопасным – изменения в одном модуле не ломают другие, если их имена не конфликтуют.
Автор: Kenchobas99
Источник [3]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/sass/447513
Ссылки в тексте:
[1] @use: https://www.pvsm.ru/users/use
[2] @forward: https://www.pvsm.ru/users/forward
[3] Источник: https://habr.com/ru/articles/1013818/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1013818
Нажмите здесь для печати.