Gatsby — nasz nowy stack do landing page

Po długim okresie realizowania tylko średnich i większych serwisów, zaczęliśmy robić więcej małych stron — landing page, strony promocyjne albo niewielkie site’y, które nie wymagają CMS-a.

Nasz wypracowany stack z Symfony na backendzie i gulpem do budowania assetów był trochę za ciężki i niepotrzebny do takich małych realizacji. Zaczęliśmy więc szukać lżejszej alternatywy. Postawiliśmy sobie takie wymagania:

  • Musi być w JavaScripcie. Zaprzęganie dodatkowych technologii do tak prostych rzeczy byłoby bezproduktywne. Skupiając się na jednym języku programowania mamy większą swobodę działania — osoby programujące frontend są samodzielne i nie muszą polegać na teamie backendowym.
  • Ma być dostosowane do Reacta; bo lubimy właśnie tę bilbiotekę ;)
  • Potrzebujemy prostego routingu, dającego możliwość tworzenia od jednej do kilku stron. Strony mogą być bezstanowe, ewentualna wymiana danych będzie realizowana przez zewnętrzne API w razie potrzeby.
  • Koniecznie chcemy SSR. Prawdopodobnie będzie to nieistotne dla większości realizacji, ale wymagań SEO nie możemy bagatelizować w naszej branży. Z jednej strony Google jakoś sobie radzi z Reactem, ale po co ryzykować? Poza tym serwowanie wygenerowanego HTML-a przydaje się również w innych sytuacjach, np. przy ustawianiu tagów open graph.

Nasz wcześniejszy stack: twig.js i gulp

Mieliśmy jeszcze taki mały projekt, który imitował to środowisko oparte o Symfony. Dawał możliwość korzystania z szablonów twigowych, do których byliśmy przyzwyczajeni. Mieliśmy tam nawet kilka popularnych funkcji / filtrów, które spełniały tę samą rolę co ich PHP-owe odpowiedniki, dzięki czemu ewentualna przesiadka na pełny stack z CMS-em miała być bezbolesna.

Niestety, większość z tych rozwiązań była napisana przez nas, a co za tym idzie wymagała utrzymania. Poza tym nie spełniała wszystkich naszych wymagań — React, SSR…

Pierwsza faza — Next.js

W pierwszym momencie obiecująco wyglądał Next.js. Po pierwsze mówimy o gotowym frameworku, a nie o zestawie narzędzi posklejanych do kupy taśmą klejącą — odpada konieczność ręcznej konfiguracji. Do tego taki stack wykorzystywany jest przez innych developerów w tym samym celu, więc łatwiej o ewentualne poprawki czy ogarnięcie specjalnych wyjątków.

Byliśmy na tyle przekonani, żeby spróbować go wdrożyć do kolejnego projektu. Niestety, na żywym organiźmie pojawiły się pierwsze problemy. Na całe szczęście, trafiły nam się dość specyficzne wymagania, które pozwoliły przetestować framework w troszkę bardziej skomplikowanej sytuacji — przejścia pomiędzy stronami były animowane.

Next ma nawet przykłady jak to zrobić, ale próba osiągnięcia oczekiwanego efektu po naszej stronie nie dała zadawalających rezultatów. Może nie przyłożyliśmy się za bardzo do zadania, ale chyba wyszło nam to na dobre, bo zaczęliśmy się oglądać za alternatywą…

Docelowe rozwiązanie — Gatsby

Akurat kilka dni wcześniej pojawił się news o nowej stronie dokumentacji Reacta napisanej w Gatsby. Tak samo jak w przypadku Next, wszystkie zabawki były gotowe od razu, wystarczyło zacząć pisać.

Podejście jest trochę inne, ale dla nas to plus. Zamiast generować HTML-a w locie, Gatsby tworzy statyczne pliki w procesie budowania aplikacji. Dzięki temu można wrzucić wynik na bucket S3, postawić przed tym CloudFronta i cieszyć się szybką i niezawodną stroną serwowaną po HTTP/2.

Jest jeszcze kilka problemów

Przeskoczenie z szablonow w całości w Twigu na komponenty w całości w React to duża zmiana. Trzeba zapomnieć o wszystkich trickach, które znaliśmy i nauczyć się nowych. To już nie nowy język szablonów, tylko dość zaawansowany JavaScript i komponenty, które z jednej strony są wyizolowane, a z drugiej muszą dobrze ze sobą współpracować.

Na pierwszy strzał przestaliśmy korzystać z modułów CSS. U nas króluje BEM i całkowita izolacja warstwy wizualnej komponentów nie była nam na rękę. A przynajmniej nie jesteśmy do tego przyzwyczajeni. Może przemyślimy tę decyzję jak nabierzemy troszkę więcej doświadczenia w Gatsbym.

Brak reduxa chcieliśmy sobie nardobić wysyłając eventy pomiędzy komponentami. Na przeszkodzie stanęły przeglądarki, które nie chciały współpracować. Nawet po zastosowaniu polyfilla logi pokazują, że przerzucane w evencie dane gdzieś się gubią. Tu nie chcieliśmy już głębiej szukać — wróciliśmy do zwykłych callbacków, przekazywanych przez kilka warstw aplikacji. Wygląda na to, że nie unikniemy zaprzyjaźnienia się z reduxem w niedalekiej przyszłości.

Sam fakt, że w dwóch pierwszych projektach musieliśmy modyfikować architekturę aplikacji w pliku html.js, co jest odradzane w dokumentacji Gatsbiego nie napawa nas optymizmem.

Po wrzuceniu zbudowanych paczek na produkcję po jakimś czasie zaczęły się pojawiać problemy. Niektóre odsłony kończyły się niezrozumiałym komunikatem błędu w konsoli, z częścią komponentów nie załadowanych. Okazało się, że winny był cache oraz fakt, że Gatsby / webpack czasami tworzy pliki o tej samej nazwie pomimo, że ich treść lekko się zmienia. Trzeba było ratować się obejściami na dzień przed wdrożeniem.

/* global process */
// gatsby-node.js

exports.modifyWebpackConfig = ({ config, stage }) => {
  if (stage === 'build-javascript' && process.env.PATH_SUFFIX) {
    const name = `[name]-[chunkhash]-${process.env.PATH_SUFFIX}.js`;
    config.merge({
      output: {
        filename: name,
        chunkFilename: name,
      },
    })
  }
  return config;
};

Na razie jesteśmy zadowoleni

Gatsby wygląda sensownie i na razie u nas zostaje. Czy sprawdzi się przy czymś troszkę większym? Zobaczymy. Jeszcze nie wszyscy się w pełni do niego przekonali, dlatego cały czas rozwijamy nasze klasyczne podejście. ;) Tymczasem efekty naszej pracy można obejrzeć na kalendarzu adwentowym LOT-u.

Maciej Łebkowski

Software Engineer, Storyteller, Leader, Generalist

Related
License

Creative Commons License
This work is licensed under a Creative Commons Attribution 4.0 International License . This means you can adapt it (even for commercial purposes), but you need to credit us by linking to this page and share it under the same license.