Wróć do strony głównej
Angular

Angular Storybook

Component Driven User Interfaces (CDUI) to podejście projektowania i tworzenia interfejsów użytkownika, które skupia się na budowaniu aplikacji poprzez połączenie małych, samodzielnych komponentów. W CDUI, każdy element UI jest traktowany jako oddzielny komponent, który może być projektowany, testowany i rozwijany niezależnie od reszty aplikacji. Głównym celem CDUI jest zwiększenie modularności i skalowalności aplikacji, a także ułatwienie tworzenia spójnego i łatwego do utrzymania interfejsu użytkownika. Poprzez budowanie aplikacji z mniejszych, samodzielnych elementów, zespoły projektowe mogą łatwiej przystosować aplikację do zmieniających się wymagań biznesowych, a także szybciej reagować na ewentualne błędy i problemy. 

Więcej o CDUI:  https://www.componentdriven.org/ 

Storybook:

Storybook to narzędzie do budowania, prezentowania i testowania komponentów interfejsu użytkownika (UI) w izolacji od reszty aplikacji. Umożliwia programistom, projektantom i testerom pracę na poszczególnych elementach UI w odizolowanym środowisku bez konieczności uruchamiania całej aplikacji.

src: https://prateeksurana.me/blog/react-component-library-using-storybook-6/

Storybook stanowi też interaktywną dokumentację komponentów, która może być łatwo udostępniona i wykorzystywana przez całe zespoły projektowe. W ramach Storybooka można tworzyć różne wersje i warianty komponentów, zasilać je różnymi danymi oraz testować je w różnych przypadkach brzegowych, co pozwala na łatwe debugowanie i wykrywanie błędów.

Jednym z kluczowych problemów, które rozwiązuje Storybook, jest zmniejszenie czasu potrzebnego na rozwój aplikacji. Dzięki możliwości pracy na pojedynczych komponentach w izolacji, programiści i projektanci mogą skupić się na rozwoju poszczególnych elementów, bez konieczności ciągłego uruchamiania całej aplikacji.

Zanim zaczniemy…

Aby w angularowym (i każdym innym) projekcie móc w pełni skorzystać z podejścia CDUI z wykorzystaniem Storybooka należy zadbać o wydzielenie interfejsu użytkownika jako osobnej (możliwie niezależnej) warstwy w aplikacji. Jednym ze sposobów na osiągnięcie tego jest wprowadzenie podziału komponentów na te odpowiedzialne za warstwę prezentacyjną (presentational components) oraz te odpowiedzialne za routing i logikę biznesową (container components). 

Więcej o takim podziale: https://blog.angular-university.io/angular-2-smart-components-vs-presentation-components-whats-the-difference-when-to-use-each-and-why/

Dla porządku warto w kodzie źródłowym wprowadzić konwencje porządkujące ten podział:

  • nazewnictwo komponentów (np. wszystkie kontenery oznaczać postfixem *-container.component.ts),
  • struktura katalogów (oba typy komponentów umieszczać w różnych odpowiednio nazwanych katalogach, np. containers i components),
  • struktura modułów (dla reużywalnych komponentów prezentacyjnych tworzyć osobne moduły/biblioteki, niezależne od reszty aplikacji),
  • osobne interfejsy dla komponentów prezentacyjnych (unikanie korzystania bezpośrednio z referencji na modele biznesowe. Niezależny interfejs dla każdego komponentu można umieścić w osobnym pliku *-foo.interface.ts zaraz obok pliku z klasą komponentu *-foo.component.ts.  Interface można również poprzedzić prefixem Ui-*, np. UiUserDetails). 

Oto przykładowa struktura zawierająca folder grupujący moduły z warstwy UI, a w nim moduł user-details zawierający komponent z interfejsem wydzielonym do osobnego pliku. W zależności od wielkości projektu struktura może być uproszczona lub bardziej złożona.

Dodanie Storybooka i pierwsze story:

Dla istniejącego projektu wystarczy uruchomić prostą komendę (znajdując się w głównym katalogu projektu):
npx storybook@latest init

Dzięki temu zainstalujemy wszystkie zewnętrzne zależności, wygenerujemy pliki konfiguracyjne, dodamy przydatne skrypty w package.json a nawet utworzymy przykładowe storybook stories. 

Po uruchomieniu komendy npm run storybook w konsoli zobaczmy mniej więcej taki output:

Pod wskazanym adresem zobaczymy uruchomionego lokalnie Storybooka, wraz z live-reloadem (każda modyfikacja komponentu spowoduje odświeżenie go w Storybooku w przeglądarce w czasie rzeczywistym).

Wróćmy teraz do naszego komponentu ‘user-details’ i rzućmy okiem na jego prostą implementację oraz przygotowany w osobnym pliku interfejs.

// user-details.interface.ts 

// user-details.component.ts

Dla takiego komponentu utwórzmy tuż obok nowy plik user-details.stories.ts

Przygotowanie obiektu meta, powiązanie go z konkretnym ui-komponentem i wyeksportowanie jako wartość domyślna pliku pozwoli nam wyświetlić różne warianty komponentu w Storybooku. W dalszej części zdefiniowaliśmy demonstracyjną wartość dla inputu user (tzw. mock), a w ostatnim kroku zdefiniowaliśmy konkretną pojedynczą story z konkretnymi danymi. Wszystko to razem już teraz pozwala nam podejrzeć gotowy komponent w Storybooku (bez uruchamiania angularowej aplikacji!):

Nieco interakcji:

Powyżej zaprezentowany został najprostszy możliwy use-case Storybooka, jednak samo narzędzie pozwala na o wiele więcej. Rozszerzmy nasz demonstracyjny komponent o dodatkowy parametr (input) notificationCount, który będzie wyświetlał liczbę oczekujących na użytkownika powiadomień (o ile jest ona większa, niż 0):

Tym razem zamiast hardcodować w pliku user-details.stories.ts kolejną demonstracyjną wartość skorzystamy z dostępnych w Storybooku kontrolek, które pozwolą dynamicznie zmieniać przekazywane do komponentu wartości.

Nasz obiekt meta należy rozbudować o dodatkowy atrybut zawierający konfigurację interaktywnych kontrolek:

Dzięki temu pozwolimy w sposób interaktywny przetestować nasz komponent dla różnych możliwych przypadków brzegowych (i bardzo szybko wykryć potencjalne błędy, jak np. ucinanie zbyt długich wartości):

W prawdziwym życiu i prawdziwych projektach nasze komponenty bywają oczywiście dużo bardziej skomplikowane. Czasem konieczne może być zaimportowanie w obiekcie meta dodatkowych zależności, zamockowanie jakichś providerów czy stworzenie wielu osobnych wariantów historyjek dla pojedynczego komponentu. Trzymając się jednak wspomnianych wcześniej zasad dot. wydzielania komponentów UI jako osobnej warstwy tworzenie i utrzymywanie Storybooka dla dowolnych komponentów jest to po prostu szybkie i wygodne. 

Kod źródłowy do pokazanego powyżej przykładu znajduje się tu:
https://github.com/Herdu/storybook-demo

Chromatic:

Chromatic to platforma, która pozwoli nam wycisnąć ze Storybooka to co najlepsze. Dzięki temu narzędziu w bardzo prosty sposób wykonamy następujące rzeczy:

  • udostępnimy gotowy katalog komponentów reszcie zespołu (w tym osobom nietechnicznym). Dajemy możliwość dodawania komentarzy, przez co mocno skrócimy feedback loop,
  • przeprowadzimy zautomatyzowane testy regresji wizualnej,
  • przetestujemy zachowanie komponentów w różnych przeglądarkach,
  • automatycznie utworzymy historię zmian UI,
  • zintegrujemy wszystko z procesami CI/CD.

    src: https://www.chromatic.com/docs/


    Dodanie Chromatica do projektu i korzystanie z niego jest proste (po więcej szczegółów odsyłam na oficjalną stronę:
    https://www.chromatic.com/), a korzyści z niego płynące wynagradzają wysiłek włożony w Storybooka.

Podsumowanie:

Przedstawione narzędzia i koncepcje pozwalają wdrożyć koncepcję CDUI w życie. Tworzenie warstwy interfejsu użytkownika może stać się zadaniem odrębnym, niezależnym, łatwym do wydelegowania innemu programiście, czy nawet innemu zespołowi. Sama praca nad komponentami staje się dużo szybsza i wygodniejsza, a testowanie przypadków brzegowych jeszcze prostsze (zarówno w momencie tworzenia, jak i w późniejszych etapach rozwoju).

Storybook, nawet w najprostszej formie, stanowi zestaw działających przykładów użycia każdego UI komponentu. Korzystając z dodatkowych rozszerzeń (np. https://storybook.js.org/addons/@storybook/addon-docs) możemy bez dodatkowej konfiguracji wygenerować pełną dokumentację naszego katalogu komponentów. 

Stawiając na reużywalność zapewnimy spójność wyglądu i zachowania naszej aplikacji. Idąc krok dalej możemy zbudować bibliotekę komponentów współdzieloną między wieloma projektami (nasze ui-komponenty mają przecież własne interfejsy, nie zależą od kontekstu biznesowego konkretnej aplikacji).  

Źródła:
„Angular UI Design Patterns & Storybook” Angular Warsaw | #5 Angular Meetup https://www.youtube.com/watch?v=PqIYMylxXCY

Dokumentacja Storybook’a https://storybook.js.org/docs/angular/

Dokumentacja Chromatic’a: https://www.chromatic.com/

O autorze

Mateusz Dobrowolski

Angular Developer w House of Angular. Sympatyk Typescripta mający kilkuletnie doświadczenie w tworzeniu Angularowych aplikacji.

Zapisz się do naszego newslettera. Bądź na bieżąco z najnowszymi trendami, poradami, meetupami i stań się częścią społeczności Angulara w Polsce. Rynek pracy docenia członków społeczności.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *