Powrót do strony głównej

Sass @use & @forward: Modułowa architektura do skalowania CSS

Artykuł szczegółowo omawia przejście Sass od przestarzałego @import do nowoczesnych dyrektyw @use i @forward. Wyjaśnione są zasady działania przestrzeni nazw, konfiguracji modułów i tworzenia publicznych API dla skalowalnej i łatwej w utrzymaniu architektury CSS.

Mistrzostwo Sass: @use i @forward dla nowoczesnej architektury CSS
Advertisement 728x90

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.

Google AdInline article slot

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:

Google AdInline article slot

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::

Google AdInline article slot
@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ściami with() zostaną zignorowane.
  • Wiele zewnętrznych bibliotek Sass używa !default dla 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 !default w 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

Advertisement 728x90

Czytaj dalej