Wróć do strony głównej
Angular

Analog: meta-framework dla Angulara

W skrócie: czym jest Analog?

Analog jest full-stackowym meta-frameworkiem przeznaczonym do budowania aplikacji
i stron internetowych z wykorzystaniem Angulara. Jest nową technologią, ponieważ pierwszy release był w 2023 roku. Możemy zatem powiedzieć, że powstało coś nowego, co – wg pogłosek – jest czymś rewolucyjnym. Powstaje zatem pytanie: 

Co Analog ma do zaoferowania? Przejrzyjmy kilka propozycji.

Wsparcie SSR/SSG

Nie od dziś wiadomo, że SSR/SSG w Angularze nie jest łatwym orzechem do zgryzienia. Z pomocą w tym temacie przychodzi biblioteka Angular Universal, jednak według powrzechnych opinii, nie jest ona wystarczająco zadowalająca. Implementacja jest trudna i ciężka w zrozumieniu oraz brakuje jej wielu przydatnych funkcji (np. routing oparty na plikach, automatyczny TransferState, obsługa zmiennych ENV), które obecnie możemy znaleźć w innych frameworkach (takich jak NextJs, SvelteKit, NuxtJS i wiele innych), a których sporą część oferuje właśnie Analog.

Jedną z wielu bolączek w Angularze z użyciem SSR jest to, że na stronie użytkownika potrafiło występować tzw. migotanie elementów (np. tekstu, obrazków), gdy zostawał podmieniany DOM renderowany po stronie klienta na DOM generowany po stronie serwera. W Angularze 16 została dodana technika hydracji, która ma za zadanie pozostawić po stronie serwera wyrenderowane komponenty podczas boostrapowania aplikacji po stronie klienta. Tym sposobem udało się częściowo rozwiązać problem migotania, jednak wciąż nie jest to idealne rozwiązanie.

Co na to Analog?

Na pewno pomocne jest to, że Analog ma domyślnie włączony SSR (z możliwością jego wyłączenia), więc nie musimy się martwić implementacją. Nie powoduje wyżej opisanego migotania treści. I jest jeszcze jeden interesujący feature – nowy sposób renderowania route’a.

Domyślnie route / jest przerenderowywany na początku podczas budowania aplikacji, dzięki czemu szybciej zwraca wygenerowany plik HTML, gdy użytkownik odwiedza główną stronę aplikacji. 

Można podać także inne ścieżki do określonych podstron i komponentów. Przerenderowywanie route’a można wykonywać asynchronicznie. Zaś by wywołać przerenderowywanie jedynie stron statycznych (SSG), wystarczy ustawić flagę static na true.

Poniżej możemy zobaczyć przykładowy kod, w którym ustawiamy ścieżki do 4 statycznych stron – strony głównej i 3 podstron.

Nie na tym jednak kończy się droga ze wsparciem SSR. Analog udostępnia wiele pluginów do różnych platform i tym sposobem umożliwia m.in. integracje angularowych komponentów z infrastrukturą Astro – czyli frameworkiem, który pozwala na tworzenie szybkich, wydajnych i interaktywnych witryn, z użyciem wymienionych technik SSR i SSG.

File-based routing

W Analogu do tworzenia routingu wykorzystywany jest układ plików, przy czym każdy plik będzie interpretowany jako route.  

Podczas tworzenia nowego projektu, Analog tworzy w strukturze folderów katalog o nazwie pages. Znajdują się tam pliki z rozszerzeniem .page.ts, gdzie każdy taki plik zostanie zmapowany na ścieżkę w routingu. Należy pamiętać, że pliki te muszą być domyślnie wyeksportowane oraz że wszystkie będą lazy-loadowane. Co więcej, w poszczególnym folderze można definiować aż 5 typów routingu: 

  • indeksowany – następuje tutaj użycie nazwy pliku ujętej w okrągłych nawiasach
    src/app/pages/(home).page.ts

Taki sposób powoduje, że w ścieżce nie będzie znajdował się segment z nazwą tego pliku, tzn. w tym przypadku pomijany jest fragment home i ścieżka rountingu wygląda tak: /

Możemy także grupować pliki w folder, którego nazwę ujmiemy w okrągłe nawiasy.

W powyższym przypadku ścieżki będą wyglądać: /login oraz /signup, zamiast /auth/login czy /auth/signup.

  • statyczny – użycie nazwy pliku bez okrągłych nawiasów
    src/app/pages/home.page.ts – tutaj ścieżka będzie wyglądać następująco: /home
    Możliwe jest również zdefiniowanie zagnieżdżonych tras statycznych na dwa różne sposoby (oba sposoby definiują ścieżkę /about/home) :
    1. src/app/pages/about/home.page.ts – użycie ukośnika jakby pliki były zagnieżdżone w folderach
    2. src/app/pages/about.home.page.ts – użycie kropki między nazwami plików
  • dynamiczny – ścieżki definiuje się przy użyciu nazwy pliku ujętego w nawiasy kwadratowe, który jest jednocześnie niejako indeksem konkretnego pliku. Parametr ten nazywa się slug parametrem.
    src/app/pages/products/[productId].page.ts – definiuje /products/:productId


Możliwe jest tutaj wykorzystanie także drugiego sposobu definiowania ścieżki z użyciem kropki – src/app/pages/products.[productId].page.ts

Jeżeli w appConfig w sekcji providers dodamy funkcję withComponentInputBinding(), będziemy mogli przy pomocy dekoratora Input pobrać parametr ze ścieżki, pod warunkiem, że i parametr i Input będą miały taką samą nazwę.

  • layout – jest zdefiniowany poprzez użycie tej samej nazwy dla pliku będącego rodzicem i folderu będącego dzieckiem

Dzięki temu pliki znajdujące się w folderze products będą pod ścieżką /products.

Plik src/app/pages/products.page.ts zawiera stronę nadrzędną zawierającą router-outlet.

Tutaj także można wykorzystać pominięcie segmentu, przy czym komponent src/app/pages/(auth).page.ts będzie posiadał router-outlet.

  • catch-all – wykorzystywany do niezidentyfikowanych ścieżek (/**), np. do obsłużenia błędu 404. W tym celu należy użyć na pliku spread operatowa w kwadratowych nawiasach – src/app/pages/[…page-not-found].page.ts

Wsparcie Vite/Vitest/Playwright

Vite to narzędzie pokroju Webpacka, ale w przeciwieństwie do niego, Vite do procesu bundlowania wykorzystuje esbuild, który jest dużo wydajniejszy i wielokrotnie szybszy, co możemy zauważyć na poniższym obrazku. 

Ponadto Vite w przeciwieństwie do Webpacka domyślnie dzieli kod na części i pobiera tylko potrzebne zależności, w efekcie czego przetworzony plik JS jest dużo mniejszy. Przykładem może być to, że Vite lazy-loaduje dependencies i jeżeli w jakimś module używamy komponentu mat-table, to będzie on załadowany dopiero po wejściu na podstronę,
która zawiera ten moduł, a nie od razu po zbudowaniu całej aplikacji.

ViTest to natywna platforma przeznaczona do testowania oprogramowania. Należy do rodziny Vite. Wtyczki i konfiguracja Vite jest kompatybilna zarówno z aplikacją jak i z testami. ViTest zawiera wsparcie dla najpopularniejszych narzędzi internetowych, takich jak TypeScript, JSX, fameworki UI, a także zapewnia szybsze uruchamianie testów jednostkowych. ViTets jest kompatybilny z Jest, zawiera całą logikę Cypressa i WebdriverIO, udoskonala Web Test Runner czy uvu. Nie jest zależny od języków programowania.

Playwright to zestaw bibliotek przeznaczonych do pisania testów automatycznych. Jest wspierany przez Microsoft od 2020 roku. Stosuje domyślnie metodę Auto-waiting, czyli czeka na odpowiednie elementy na stronie, zanim podejmie jakieś działanie. Jego selektory potrafią się odnosić do elementów Shadow DOM. Wspiera języki TypeScript, JavaScript, Python, .NET, Java.

Możliwość tworzenia plików typu Markdown

Warto wspomnieć, że jedną z wielu zalet Analoga jest możliwość przechwytywania plików typu Markdown w procesie renderowania. Dodatkowo można ich użyć jako ścieżek w routingu, dzięki czemu ich zawartość zostanie wygenerowana jako oddzielna strona.

Markdown jest jednym z języków markup (innym jest np. HTML) do tworzenia plików tekstowych z możliwością nadawania styli na tekst, takich jak akapity, nagłówki, pogrubienie, kursywa i wiele innych. Dzięki temu osoba tworząca prosty plik, np. artykuł na bloga, nie musi znać zasad tworzenia plików HTML i CSS.

Przykładowy wygląd pliku Markdown oraz jego efekt:

 

Pliki Markdown umieszczone w folderze src zostaną automatycznie pobrane i wyrenderowane po zdefiniowaniu routingu.

Aby wyświetlić taki plik musimy wykonać kilka czynności:

  • w pliku app.config.ts w tablicy providers włączyć możliwość renderowania plików markdown przy pomocy funkcji provideContent() oraz withMarkdownRenderer()

  • umieścić plik w folderze src/app/pages z rozszerzeniem .md, np. src/app/pages/example.md
  • pobrać treść i wyświetlić ją w templatce przy pomocy providera MarkdownComponent, funkcji injectContent() oraz komponentu <analog-markdown></analog-markdown>.

Komponent wie, z którego miejsca ma pobrać zawartość pliku, ponieważ dostaje tę informację ze ścieżki routingu /src/app/pages/blog/posts.[slug].page.ts  

Podsumowanie

Podsumowując Analog posiada wiele nowoczesnych funkcji i rozwiązań, które ułatwiają oraz przyspieszają pracę tworzenia witryn. Stara się jak najlepiej wykorzystywać SSR/SSG, udostępnia prosty sposób na używanie markdownów, automatyzuje tworzenie routingu, upraszcza pisanie testów oraz używa najnowszego bundlera. A jest to tak naprawdę sam początek, bo Analog dopiero zaczyna się rozwijać i to na pewno nie wszystko, co ma nam – deweloperom – do zaoferowania.

O autorze

Maja Hendzel

Angular Developer w House of Angular. Jedyna przedstawicielka teamu Fifa. Lubi klepać dobry kod.

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.

Leave a Reply

Your email address will not be published. Required fields are marked *