Директива `@forward` в SASS
В этой статье объясняется, как работает директива @forward в SASS.
Мы объясним @forward простым и понятным способом, приводя практические примеры.
YouTube Video
Директива @forward в SASS
Что такое @forward?
В модульной системе SASS вместо @import используются @use и @forward. @forward — это важная функция для поддержания чистоты архитектуры. Это директива, используемая для «экспонирования» переменных, миксинов и функций, определённых в других файлах. Вместо самостоятельного использования она служит точкой входа, указывая: 'Используйте этот модуль отсюда.'.
1@forward "variables";- Этот код означает, что содержимое файла
variables.scssстановится доступным для использования из других файлов.
Разница между @use и @forward
@use и @forward — это оба способа работы с модулями, но их назначения чётко различаются. @use — это директива для использования элементов внутри файла, а @forward — директива для предоставления этих элементов другим файлам.
1// @use: import the module for use in this file
2@use "variables";
3
4// @forward: re-export the module for other files to consume
5@forward "variables";@useобозначает зависимости, необходимые для реализации текущего файла, в то время как@forwardпревращает файл в точку входа публичного API. Понимание этой разницы поможет вам решить, где использовать@forward.
Зачем нужен @forward?
С добавлением новых файлов Sass вам, возможно, придётся писать много инструкций @use. С помощью @forward вы можете собрать всё в одном файле-энтрипойнте.
1styles/
2├─ foundation/
3│ ├─ _variables.scss
4│ ├─ _mixins.scss
5│ └─ _index.scss
6└─ main.scss- В такой структуре файл
_index.scssвыполняет роль 'публичного API.'.
Базовое использование @forward
Давайте рассмотрим базовое использование @forward.
1// _variables.scss
2// Color definitions used across the project
3
4$primary-color: #006ab1;
5$secondary-color: #e0f0ff;
6
7// Internal use only (will be hidden via @forward hide)
8$debug-color: magenta;- Вместо того чтобы прямо использовать переменную через
@use, вы группируете их с помощью@forward.
1// _index.scss
2@forward "variables";- На этом этапе файл
_index.scssне содержит ничего — это просто файл-посредник.
Использование модулей, экспортированных через @forward
Вместо того чтобы использовать отдельные файлы через @use, на стороне пользователя вы используете только индексный файл, который группирует все @forward. Это позволяет использовать стабильный интерфейс, не задумываясь о внутренней структуре.
1// main.scss
2// Import the public API of the foundation layer
3@use "foundation";
4
5.button {
6 background-color: foundation.$primary-color;
7}- С такой структурой, даже если местоположение переменных или миксинов изменится, вы сможете изменить внутреннюю организацию без необходимости модифицировать что-либо на стороне пользователя.
Объединение нескольких модулей с помощью @forward
В реальной разработке принято разделять переменные, миксины и функции в зависимости от их назначения. @forward можно использовать несколько раз, что позволяет объединить разделённые модули в единый публичный API.
Ниже мы приводим примеры миксинов и функций и показываем архитектуру, которая предоставляет их наружу как единый интерфейс.
1// _mixins.scss
2// Reusable mixins for layout and components
3
4// Reset default button styles
5@mixin button-reset {
6 appearance: none;
7 background: none;
8 border: none;
9 padding: 0;
10 margin: 0;
11 font: inherit;
12 color: inherit;
13}
14
15// Clearfix utility
16@mixin clearfix {
17 &::after {
18 content: "";
19 display: table;
20 clear: both;
21 }
22}
23
24// Internal mixin (not intended to be part of the public API)
25@mixin debug-outline {
26 outline: 2px dashed red;
27} 1// _functions.scss
2// Utility functions for consistent styling
3
4@use "sass:math";
5
6// Convert px to rem based on a 16px root size
7@function rem($px) {
8 @return math.div($px, 16) * 1rem;
9}
10
11// Clamp a value between a minimum and maximum
12@function clamp-value($value, $min, $max) {
13 @return math.max($min, math.min($value, $max));
14}1// _index.scss
2// Re-export variables, mixins, and functions as a single public API
3@forward "variables";
4@forward "mixins";
5@forward "functions";- Открывая наружу только файл
index, вы можете скрыть внутреннюю структуру и предоставить удобный интерфейс для пользователей.
Предотвращение конфликтов имён (через as)
Если одинаковые переменные или миксины определены в разных модулях, вы можете указать as в @forward, чтобы добавить префикс и предотвратить конфликт имён.
1// Add a prefix when re-exporting to avoid name collisions
2@forward "variables" as var-*;С этим кодом $primary-color из модуля variables будет экспортироваться под следующим именем:.
1// foundation.$var-primary-color- Этот приём — способ чётко определять правила дизайна и безопасно масштабироваться, и он крайне важен, особенно в крупных проектах и общих библиотеках.
Сокрытие ненужных элементов (через hide)
Модули могут содержать переменные или миксины, предназначенные только для внутреннего использования. С помощью директивы hide вы можете исключить их при переоткрытии и не позволить обращаться к ним извне.
1// Re-export everything except internal debug variables
2@forward "variables" hide $debug-color;С такой конфигурацией $debug-color действует только внутри модуля, что помогает предотвратить случайное использование.
Указание, какие элементы экспортировать (через show)
Если вы хотите экспортировать только определённые миксины или функции, используйте директиву show. Ограничивая то, что экспонируется, вы можете прояснить назначение модуля и замысел его архитектуры.
1// Explicitly expose only selected mixins as the public API
2@forward "mixins" show button-reset, clearfix;- Используя
showтаким образом, становится сразу видно, какие API официально разрешено использовать.
@forward не может использоваться автономно
Важно: переменные, экспортированные через @forward, нельзя использовать внутри того же файла.
1@forward "variables";
2
3.test {
4 color: $primary-color; // Error
5}@forwardпредназначен только для 'переэкспорта', а за 'использование' отвечает@use.
Пример правильного разделения ролей
В SASS-модулях желательно чётко разделять публичный уровень (API) и уровень реализации. @forward определяет публичный API, а @use — использует его на стороне реализации.
1// _index.scss (public API)
2@forward "variables";
3@forward "mixins";1// _component.scss
2// Consume the public API of the foundation layer
3@use "foundation";
4
5.card {
6 color: foundation.$primary-color;
7}- В такой структуре становится понятно, что является публичным интерфейсом, а что внутренней реализацией, что способствует лучшей прозрачности.
Ключевое отличие от @import
@import раскрывает все импортированные определения в глобальную область видимости. В то время как @use и @forward явно экспортируют элементы и предоставляют к ним доступ через пространства имён.
1// @import (deprecated)
2// Everything is injected into the global scope
3$color: red;
4
5.button-import {
6 color: $color;
7}
8
9// @use + @forward (recommended)
10// Access values explicitly through a namespace
11@use "foundation";
12
13.button-use {
14 color: foundation.$primary-color;
15}- Благодаря этой разнице, можно значительно повысить поддерживаемость и безопасность, предотвращая случайные перезаписи и путаницу в зависимостях.
Резюме
@forward — это существенная функция, поддерживающая хорошо сопровождаемый дизайн. Продумывая, что экспортировать, а что скрывать как внутреннюю реализацию, вы делаете архитектуру своих стилей более безопасной и понятной. Грамотно используя @use и @forward, вы сможете явно указывать зависимости и создавать архитектуру, устойчивую к изменениям.
Вы можете следовать этой статье, используя Visual Studio Code на нашем YouTube-канале. Пожалуйста, также посмотрите наш YouTube-канал.