Sass: Od przestarzałego @import do nowoczesnej architektury modułowej z @use i @forward
W świecie rozwoju frontendowego, gdzie projekty stają się coraz bardziej złożone, a baza kodu rozrasta się, efektywne zarządzanie stylami nabiera krytycznego znaczenia. Sass, jako jeden z wiodących preprocesorów CSS, przeszedł znaczące zmiany, mające na celu poprawę modułowości i łatwości utrzymania kodu. Kluczowym etapem tej ewolucji było odejście od przestarzałej dyrektywy @import na rzecz potężnych i elastycznych @use i @forward.
Przez długi czas @import był jedynym sposobem na dołączanie plików Sass, ale miał istotne wady: globalne zanieczyszczenie przestrzeni nazw, wysokie ryzyko konfliktów i duplikowanie kodu. Wraz ze zbliżającą się premierą Dart Sass 3.0.0, @import został oficjalnie uznany za przestarzały i zostanie całkowicie usunięty, co czyni opanowanie nowego systemu modułowego obowiązkowym dla każdego nowoczesnego programisty.
Dyrektywa @use: Izolacja i Przestrzenie Nazw
@use to fundamentalny element nowego systemu modułowego Sass. Ładuje plik Sass (moduł) i udostępnia jego zawartość (zmienne, miksiny, funkcje) w bieżącym pliku, ale jednocześnie izoluje ją w jego własnej przestrzeni nazw. To kluczowa różnica w stosunku do @import, która zapobiega globalnym konfliktom i sprawia, że zależności są jawne.
Podstawowe użycie:
@use 'ścieżka/do/pliku';
Domyślnie nazwa przestrzeni nazw jest tworzona z ostatniej części ścieżki do pliku, bez podkreśleń i rozszerzeń. Na przykład, używając @use '../helpers/colors'; zmienne i funkcje z _colors.scss będą dostępne poprzez prefiks colors.:
// helpers/_colors.scss
$primary: blue;
$secondary: gray;
// components/_button.scss
@use '../helpers/colors';
.button {
color: colors.$primary; // Odwołanie przez przestrzeń nazw "colors"
background-color: colors.$secondary;
}
Zmiana przestrzeni nazw za pomocą as:
Dla wygody lub jasności można nadać niestandardową nazwę modułowi, używając słowa kluczowego as:
@use 'helpers/colors' as myColors;
.button {
color: myColors.$primary; // Odwołanie przez "myColors"
}
Przy nazywaniu przestrzeni nazw należy przestrzegać zasad dla identyfikatorów Sass:
- Dozwolone: litery (a-z, A-Z), cyfry (0-9, ale nie na początku),
camelCase,PascalCase. - Niedozwolone: łączniki (
-), spacje, znaki specjalne, rozpoczynanie od cyfry.
Użycie Wbudowanych Modułów Sass
Sass udostępnia zestaw wbudowanych modułów do typowych zadań, takich jak operacje matematyczne, praca z listami, mapami, kolorami i ciągami znaków. Moduły te są dołączane z prefiksem sass::
@use 'sass:math';
@use 'sass:list';
@use 'sass:map';
@use 'sass:color';
@use 'sass:string';
Przykłady użycia funkcji z wbudowanych modułów:
$width: math.div(100%, 3); // Dzielenie
$len: list.length((10px, 20px, 30px)); // Długość listy
$color: color.adjust(#336699, $lightness: 20%); // Korekcja koloru
$index: string.index('hello world', 'world'); // Wyszukiwanie podciągu
Ważne jest, aby pamiętać, że wbudowane moduły, podobnie jak zwykłe, muszą być jawnie dołączone w każdym pliku, w którym używane są ich funkcje. Nie są one dziedziczone przez inne importy.
Organizacja Kodu i Dostęp do Modułów
System modułowy Sass promuje podejście, w którym każdy plik SCSS jawnie deklaruje swoje zależności na początku. Zapewnia to przejrzystość i upraszcza refaktoryzację. Miksiny i funkcje zdefiniowane w plikach użytkownika są również dostępne poprzez przestrzenie nazw.
Przykład definicji miksina:
// helpers/_mixins.scss
@mixin flex-center {
display: flex;
align-items: center;
justify-content: center;
}
I jego użycie:
// components/_card.scss
@use '../helpers/mixins';
.card {
@include mixins.flex-center;
}
Zalecana struktura folderów:
Dobrze ustrukturyzowany projekt Sass może wyglądać następująco:
scss/
helpers/
_colors.scss
_variables.scss
_mixins.scss
components/
_button.scss
_card.scss
pages/
_about-page.scss
template.scss // Główny plik kompilacji
Przykład pliku komponentu, używającego kilku modułów:
// 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;
}
Zalety podejścia modułowego z przestrzeniami nazw:
- Jawność: Od razu widać, z którego modułu pochodzi zmienna lub miksin, co poprawia czytelność kodu.
- Brak konfliktów: Izolowane przestrzenie nazw gwarantują, że zmienne i miksiny o tych samych nazwach w różnych modułach nie będą ze sobą kolidować.
- Łatwa refaktoryzacja: Zmiany w jednym module nie wpływają na inne, jeśli nie narusza to ich API, co upraszcza skalowanie i modyfikację.
- Wsparcie IDE: Nowoczesne środowiska programistyczne lepiej współpracują z jawnymi przestrzeniami nazw, oferując precyzyjne autouzupełnianie.
- Skalowalność: Baza kodu pozostaje zrozumiała i łatwa do zarządzania nawet w bardzo dużych projektach.
Konfiguracja Modułów z @use ... with()
Dyrektywa @use ... with() zapewnia potężny mechanizm do konfigurowania modułów podczas ich importowania. Pozwala ona nadpisywać zmienne oznaczone jako !default, przekazując nowe wartości bezpośrednio podczas dołączania modułu.
Jak działa !default:
Zmienna zadeklarowana z !default używa swojej wartości tylko wtedy, gdy nie została wcześniej ustawiona. Jeśli wartość jest już ustawiona (na przykład w innym pliku lub poprzez @use ... with()), !default jest ignorowane.
// helpers/_theme.scss
$bg-color: #ffffff !default; // Wartość domyślna
$text-color: #333333 !default; // Może być nadpisana
Nadpisywanie wartości za pomocą with():
Możesz przekazać nowe wartości dla zmiennych !default w nawiasach with() podczas importowania modułu:
// pages/dark-theme.scss
@use '../helpers/theme' with (
$bg-color: #1a1a1a,
$text-color: #f0f0f0
);
body {
background: theme.$bg-color; // Będzie #1a1a1a
color: theme.$text-color; // Będzie #f0f0f0
}
Ważne uwagi dotyczące with():
@use ... with()działa tylko przy pierwszym imporcie konkretnego modułu w danym pliku. Wszystkie kolejne próby importowania tego samego modułu z innymi wartościamiwith()zostaną zignorowane.- Wiele zewnętrznych bibliotek Sass używa
!defaultdla swoich ustawień, co pozwala łatwo dostosować ich zachowanie za pomocąwith().
Dyrektywa @forward: Tworzenie Publicznego API
@forward to dyrektywa, która pozwala przekazywać zawartość jednego lub więcej modułów dalej, udostępniając je innym plikom, które importują plik pośredniczący. Jest używana do tworzenia jednolitego punktu wejścia (publicznego API) dla zestawu modułów, nie udostępniając ich jednocześnie w pliku, w którym używane jest @forward.
Przykład użycia _core.scss jako jednolitego punktu wejścia:
// _core.scss
@forward 'helpers/colors';
@forward 'helpers/variables';
@forward 'base/fonts';
@forward 'helpers/mixins';
Teraz, zamiast importować każdy plik osobno, można po prostu dołączyć _core.scss:
// pages/about-page.scss
@use '../core.scss';
.button {
color: core.$blue; // Zmienna z helpers/colors
border-radius: core.$border-radius-medium; // Zmienna z helpers/variables
@include core.flex-center; // Miksin z helpers/mixins
}
Plusy i minusy podejścia _core.scss:
- Plus: Upraszcza importy w końcowych plikach, tworząc jasne API dla całego projektu.
- Minus: Wszystkie przekazane elementy używają przestrzeni nazw
core(lub zdefiniowanej przez ciebie), co może utrudnić określenie oryginalnego pliku dla konkretnej zmiennej lub miksina bez przeglądania_core.scss.
Wewnętrzne użycie przekazanych modułów:
Jeśli w samym pliku _core.scss wymagane jest użycie zmiennych lub miksinów z przekazywanych modułów, należy je dodatkowo zaimportować za pomocą @use:
// _core.scss
@forward 'helpers/colors'; // Przekazanie na zewnątrz
@use 'helpers/colors' as c; // Do użycia wewnątrz _core.scss
body {
background: c.$bg-color; // Działa dzięki @use
}
Rozszerzone możliwości @forward:
- Selektywne przekazywanie (
show/hide): Pozwala jawnie określić, które dokładnie elementy modułu mają być przekazane.
```scss
@forward 'colors' show $primary, $secondary; // Przekaż tylko te zmienne
@forward 'mixins' hide private-mixin; // Przekaż wszystko, oprócz private-mixin
```
- Konfiguracja za pomocą
with()podczas przekazywania: Podobnie jak@use ... with(), można nadpisywać zmienne!defaultw przekazywanym module.
```scss
// helpers/_theme.scss
$bg-color: #fff !default;
// _index.scss (plik, który będzie forward'ował _theme.scss)
@forward 'theme' with (
$bg-color: #f0f0f0
);
```
Zarządzanie Zależnościami Między Modułami
W systemie modułowym Sass każdy plik musi jawnie wskazywać swoje zależności. Dotyczy to również przypadków, gdy jeden z twoich modułów (np. _variables.scss) używa zmiennych z innego modułu (_colors.scss). Nawet jeśli _variables.scss i _colors.scss są oba przekazywane przez _core.scss, _variables.scss nadal musi jawnie zaimportować _colors.scss, jeśli go używa.
// _variables.scss
@use 'colors'; // Jawna zależność od _colors.scss
$button-bg: colors.$primary;
Dlaczego to jest ważne:
- Jawność: Od razu widać, od jakich modułów zależy każdy plik, co upraszcza zrozumienie struktury.
- Niezawodność: Podczas przenoszenia lub reorganizacji plików zależności pozostają nienaruszone i zrozumiałe.
- Wsparcie IDE: Narzędzia do analizy statycznej i autouzupełniania działają dokładniej.
- Refaktoryzacja: Łatwo śledzić, gdzie używane są konkretne moduły i zmienne.
Co ważne
- @use i @forward zastępują przestarzałe
@import, oferując prawdziwą modułowość w Sass. - Przestrzenie nazw zapobiegają konfliktom i sprawiają, że zależności są jawne, poprawiając skalowalność.
- @use ... with() pozwala elastycznie konfigurować moduły, nadpisując zmienne oznaczone
!default. - @forward jest używane do tworzenia jednolitych punktów wejścia (publicznych API), upraszczając zarządzanie dużą liczbą modułów.
- Jawne deklarowanie zależności w każdym pliku jest krytyczne dla łatwości utrzymania i przewidywalności kodu Sass.
— Editorial Team
Brak komentarzy.