Blog

Gatsby cz. 1 - instalacja

Data publikacji: 2021-07-19

Ostatnia edycja: 2021-07-22

Stały adres serii wpisów o Gatsbym - /blog/gatsby

Start!

Plan tego odcinka jest następujący:

  • Podstawowe informacje.
  • Sposoby instalacji.
  • Gatsby From Scratch.
  • Struktura plików.
  • Strony Home i 404 z komponentem Link.

A więc do dzieła!

Podstawowe informacje

JavaScript to język programowania wprowadzony w przeglądarkach internetowych w 1995. Bardzo długo prymitywne narzędzie do uzyskania efektów na stronach typu padający śnieg, czy przesuwający się napis. Ograniczeniem był fakt, że jedynym środowiskiem uruchomieniowym był silnik przeglądarki. Kod JS można było umieścić na stronie WWW. Po jej uruchomieniu w przeglądarce mógł się wykonywać tylko lokalnie, nie mając żadnej łączności z serwerem. Rozwiązanie tylko client-side. Do poważnych zastosowań używano PHP, który z kolei był i wciąż jest serwer-side.

Zmieniło się to w końcu pierwszej dekady XXI wieku.

  • 2009 Node.js niezależny od przeglądarki silnik JS, który można uruchomić na serwerze, więc od tego czasu JS jest również server-side. Powstaje również dziś najważniejsza baza danych NoSQL: MongoDB. Umożliwia wykonywanie kodu JS.
  • 2010 Google: AngularJS, pierwszy poważny framework JS.
  • 2012 Microsoft: TypeScript
  • 2013 Facebook: React biblioteka tworzenia komponentów JS. Ecma International standaryzuje JSON-a: ECMA-404 i RFC 7158
  • 2014 Vue.
  • 2015 ES6 czyli ECMAScript 2015, JS zaczyna się naprawdę dynamicznie rozwijać. Facebook tworzy GraphQL.
  • 2016 Next.js, ponadto Google wycofuje się z AngularJS, powstaje Angular.
  • 2017 Gatsby.js kreator statycznych stron, framework Reacta.
  • 2020 Deno 1.0 - Ryan Dahl, twórca Node'a niezadowolony z kierunku jego rozwoju, stworzył jego alternatywę. Czy osiągnie sukces? Zobaczymy.

Bo dobrze. Ale czym właściwie jest Gatsby i dlaczego warto się nim zainteresować? Przecież jest WordPress...

Wcale nie ironizuję. WordPress jest i pozostanie najważniejszym system publikacji treści. Szacunki są różne, nie jest to łatwo policzyć, ale na pewno ponad połowa stron WWW to WordPress. Największa i najlepsza konkurencja nic tu nie zmieni.

Wciąż jest wiele zastosowań, w których dobrze znane i sprawdzone w boju CMS-y takie jak WordPress są najlepszym rozwiązaniem. Jest jednak ogromny sektor rynku, w którym już są i zawsze będą gorszą opcją. To wcale nie jest przypadek ani fanaberia, że witryny wielu wielkich brandów są zbudowane na Reaccie (oj jak to się źle odmienia!)... dobrze, przy użyciu Reacta, Nexta czy Gatsby'ego. Dlaczego tak postąpili, to jest temat na osobną dyskusję i tu zapraszam zarówno na znakomity film Adama Romańskiego "React vs. Next vs. Gatsby – czym się różnią? ⌨️ hello roman #84" [YT 18:19], jak i wstęp w mocno już w tej chwili przestarzałym i wymagającym poprawy moim artykule o Gatsby'm. Jego początek może być wprowadzeniem w tę tematykę.

W skrócie: React jest diablo szybkim i relatywnie łatwym (przynajmniej w podstawach) do poznania prawie-frameworkiem (formalnie to biblioteka) JS. I można w nim tworzyć strony. Wadą jest słabe SEO. Gatsby opakowuje wszystkie dobre właściwości Reacta dodając - no właśnie - framework wyspecjalizowany do tworzenia stron i aplikacji WWW. Gatsby to też React i wszystko, co możesz zrobić w Reaccie, możesz zrobić w Gatsbym. Sama strona Reacta jest napisana w Gatsbym. W każdym razie prawie wszystko, ponieważ jest to głównie generator stron statycznych, nie zawsze jest to dobry pomysł.

Gatsby najlepiej sprawdza się tam, gdzie aktualizacje treści nie są zbyt częste. Na przykład na mojej stronie nie przewiduję częstszej aktualizacji niż raz dziennie i tu Gatsby jest świetnym rozwiązaniem. Jest szybki, jest zoptymalizowany, nie potrzebuje bazy danych, jest też elastyczny - bo to JavaScript i można w nim napisać wszystko. Nawet jeśli by mi padł komputer, całe archiwum strony mam na GitHubie. Hosting zapewnia Netlify, który jest zupełnie za darmo do 300 minut buildu miesięcznie i nigdy tego limitu nie przekroczyłem, a mam tam wiele stron. Netlify daje świetny, skutecznie filtrujący spam formularz kontaktowy oraz SSL, również gratis. Inną opcją jest Gatsby Cloud.

Treść stron Gatsby'ego to znany z Reacta JSX lub pliki Markdown (albo .md, albo .mdx). Dodatkowo można skonfigurować go tak, żeby nową treść dodawać z innych źródeł tzw. Headless CMS-ów. Czyli edytor loguje się na WordPressa, tam pisze artykuł w znanym sobie środowisku edycyjnym, klika i - cyk! - Gatsby na serwerze budzi się, pobiera nową treść, kompiluje się na nowo i po pewnym czasie (tyle ile zajmuje build, u mnie jest to zwykle 6 minut), nowy artykuł pojawia się online.

Ma to tę zaletę, że zbuildowana strona statyczna jest odporna na atak, a edycji i dodawania treści można dokonywać w osobnym środowisku. Natomiast wadą jest to, że dodanie wymaga kompilacji, której czas wciąż jest największą bolączką Gatsby'ego.

Wymagania

Potrzebujemy zainstalować trzy rzeczy:

  • System kontroli wersji Git.
  • Node.js, z którym domyślnie dostajemy system zarządzania pakietami npm, alternatywnie może być to też yarn.
  • gatsby-cli jak sama nazwa wskazuje CLI (Command Line Interface) Gatsby'ego. Instalowany poleceniem npm i -g gatsby-cli.

Opcjonalnie do zarządzania różnymi wersjami Node'a - nvm-sh / nvm

Deweloping

Jeszcze zanim przejedziemy do instalacji, trzeba wyjaśnić jedną rzecz - jak wygląda tworzenie i publikacja strony w Gatsbym.

  • Instalacja - opisana poniżej - trzeba mieć świadomość, że cały katalog ze środowiskiem deweloperskim zajmuje od 250 do ponad 500 MB.
  • Uruchomienie środowiska deweloperskiego poleceniem gatsby develop, na tym etapie dokonuje się właściwe tworzenie strony. Efekt widoczny jest pod adresem localhost:8000. środowisko zapewnia hot-loading, co znaczy, że reaguje na dokonane zmiany, zapisuje je i od razu przerysowuje stronę, ale trzeba mieć świadomość, że każda zmiana w którymś z plików konfiguracyjnych /gatsby-*.js wymaga restartu środowiska, a to zajmuje zależnie od wielkości strony od minuty do ponad 10 minut. Wiec od razu przygotuj sobie jakąś książkę do poczytania na boku ;-)
  • Build, ciężko to przetłumaczyć na polski, bo "budowanie" niewiele tu mówi. Samo środowisko deweloperskie zapewnia serwer i działanie strony, ale jest to bardzo nieoptymalne, strony są generowane w locie i jak już pisałem, wszystko wymaga ponad 200 MB miejsca oraz dość sporej mocy obliczeniowej. Natomiast build kompiluje to, co napisaliśmy, łącznie z udostępnionymi zasobami w zoptymalizowany, statyczny produkt końcowy. Build uruchamia się poleceniem gatsby build. Zajmuje to - takie mam wrażenie - trochę krócej niż uruchomienie środowiska deweloperskiego. Ponieważ rysuje od razu całą stronę, jest też bardziej wymagające. Build potrafi wywalić się na kodzie, który dla środowiska deweloperskiego był OK. Więc po każdej poważniejszej zmianie, przed wysłaniem na serwer dobrze jest sprawdzić, czy działa build lokalny. Żeby zobaczyć stronę tak zbudowaną, uruchamiany serwer poleceniem gatsby serve i po chwili możemy zobaczyć pod adresem localhost:9000. To, co zobaczymy to statyczny efekt, który nie podlega zmianom.
  • Deploy czyli wysłanie na serwer zewnętrzny, publikacja strony online. O tym będzie w osobnym wpisie. Jeżeli kod się nie skompiluje na serwerze, poprzednia wersja strony pozostaje.

Najkrócej mówiąc:

  • gatsby develop to jest wersja deweloperska, zmienia się na bieżąco.
  • gatsby build to jest wersja produkcyjna, statyczna.

Tak więc podstawowe polecenia:

  • gatsby develop - uruchomienie środowiska deweloperskiego
  • gatsby build - kompilacja, utworzenie zoptymalizowanej, końcowej strony w katalogu /public
  • gatsby serve - uruchomienie serwera dla buildu
  • gatsby clean - czyszczenie bufora, kasuje katalogi .cache i public
  • npm outdated - sprawdzenie czy mamy jakieś pakiety Node'a do aktualizacji
  • npm update - update wszystkich pakietów

Więcej o pakietach w osobnym wpisie im poświęconym.

Instalacja

Można zainstalować na kilka sposobów:

  • przy użyciu startera: Gatsby Starters | Gatsby Starters
  • interaktywnie, wymaga pewnej znajomości środowiska, a przede wszystkim orientacji w tym, czego potrzebujemy, szerzej opisane jest tutaj, w API Commands polecenie "new": Commands (Gatsby CLI)
  • nieinteraktywnie
  • Gatsby from Scratch i tę instalację tutaj opiszę, pozwala ona poznać Gatsby'ego lepiej o zobaczyć jak wygląda od podstaw.

Instalacja nieinteraktywna - używa domyślnego startera:

$ gatsby new gatsbysite
info Creating new site from git: https://github.com/gatsbyjs/gatsby-starter-default.git

Klonowanie do „gatsbysite”...
remote: Enumerating objects: 28, done.
remote: Counting objects: 100% (28/28), done.
remote: Compressing objects: 100% (26/26), done.
remote: Total 28 (delta 3), reused 8 (delta 0), pack-reused 0
Pobieranie obiektów: 100% (28/28), 612.86 KiB | 1.93 MiB/s, gotowe.
success Created starter directory layout
info Installing packages...


added 2362 packages, and audited 2363 packages in 37s

44 vulnerabilities (36 moderate, 6 high, 2 critical)

To address issues that do not require attention, run:
  npm audit fix

To address all issues (including breaking changes), run:
  npm audit fix --force

info Initialising git in gatsbysite

podpowiedź: Użycie „master” jako nawy początkowej gałęzi. Ta domyślna nazwa gałęzi
podpowiedź: może się zmienić. Aby ustawić nazwę początkowej gałęzi do użycia we
podpowiedź: wszystkich nowych repozytoriach, co uciszy ten komunikat, wykonaj:
podpowiedź: 
podpowiedź:     git config --global init.defaultBranch <nazwa>
podpowiedź: 
podpowiedź: Tradycyjnie było „master”, a inne popularne to „main”, „trunk”
podpowiedź: i „development”. Nazwę właśnie utworzonej gałęzi można zmienić tym poleceniem:
podpowiedź: 
podpowiedź:     git branch -m <nazwa>
info Create initial git commit in gatsbysite
info
Your new Gatsby site has been successfully bootstrapped. Start developing it by running:

  cd gatsbysite
  gatsby develop

jak widać, na końcu podpowiada co zrobić, żeby uruchomić środowisko deweloperskie.

Zawsze czytajcie komunikaty, szczególnie komunikaty błędów.

Gatsby From Scratch

Żeby utworzyć działającą stronę w trybie instalacji od zera, potrzebne są następujące działania:

  • utworzenie katalogu
  • inicjalizacja npm
  • inicjalizacja gita
  • instalacja Reacta i Gatby'ego
  • utworzenie pliku konfiguracyjnego gatsby-config.js
  • utworzenie plików stron w /src/pages; potrzebujemy przynajmniej dwóch: index.js i 404.js

Najpierw trzeba utworzyć katalog, w którym powstanie strona (w tym przykładzie: gfs). Będzie to katalog główny strony.

Przechodzimy do tego katalogu głównego strony i wydajemy trzy polecenia, pierwsze tworzy package.json zawierający kompletną informację o zainstalowanych pakietach Node'a (na razie nie ma żadnych), drugie inicjalizuje repo gita, trzecie instaluje Reacta i Gatsby'ego:

$ mkdir gfs
$ cd gfs
gfs$ npm init -y
gfs$ git init
gfs$ npm i gatsby react react-dom

Dokładnie wygląda to tak:

  1. Utworzenie npm
$ npm init -y
Wrote to /media/tadek/shared/GitShared/Gatsby/hmp-archive/hmp-test/package.json:

{
  "name": "hmp-test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}
  1. Inicjalizacja repozytorium gita:
$ git init
podpowiedź: Użycie „master” jako nawy początkowej gałęzi. Ta domyślna nazwa gałęzi
podpowiedź: może się zmienić. Aby ustawić nazwę początkowej gałęzi do użycia we
podpowiedź: wszystkich nowych repozytoriach, co uciszy ten komunikat, wykonaj:
podpowiedź:
podpowiedź:     git config --global init.defaultBranch <nazwa>
podpowiedź:
podpowiedź: Tradycyjnie było „master”, a inne popularne to „main”, „trunk”
podpowiedź: i „development”. Nazwę właśnie utworzonej gałęzi można zmienić tym poleceniem:
podpowiedź:
podpowiedź:     git branch -m <nazwa>
Zainicjowano puste repozytorium Gita w /media/tadek/shared/GitShared/Gatsby/hmp-archive/hmp-test/.git/

Dobrze jest od razu utworzyć plik .gitignore w katalogu głównym strony:

# Project dependencies
.cache
node_modules
# Build directory
public
# Other
.DS_Store
*.log
  1. Instalacja Reacta i Gatsby'ego:
$ npm i gatsby react react-dom

Efekt wygląda tak:

$ ls -A
.git .gitignore node_modules package.json package-lock.json

Całość zajmuje ok. 250 MB.

Ponieważ w tego typu instalacji nie używamy żadnego startera, wszystkie katalogi i pliki konfiguracyjne trzeba stworzyć samemu. Są dwa plusy takiego postępowania: 1) nie powstaną żadne niepotrzebne 2) nie jest ich wiele.

Przede wszystkim jest to główny katalog, w którym powstaje strona, czyli /src oraz główny katalog konfiguracyjny, czyli /gatsby-config.js.

Plik gatsby-config.js na starcie może wyglądać tak:

gatsby-config.js

module.exports = {
    siteMetadata: {
        title: `tytuł strony`,
        description: `opis strony`,
    },
    plugins: [
// tu umieszczamy deklaracje zainstalowanych pluginów
    ],
}

przykładowy package.json

  "scripts": {
    "build": "gatsby build",
    "develop": "gatsby develop",
    "start": "npm run develop",
    "serve": "gatsby serve",
    "clean": "gatsby clean",
  },

Struktura katalogów i plików

Uwaga, poniżej przedstawiona jest docelowa struktura, część z nich tworzona jest w procesie buildowania, część z nich nie będzie nam potrzebna. Cała nasza praca ogranicza się do katalogu /src oraz plików konfiguracyjnych w katalogu głównym: przede wszystkim gatsby-config.js, czasem też gatsby-node.js, dużo rzadziej gatsby-browser.js i gatsby-ssr.js.

  • /.cache - jak sama nazwa wskazuje, jest to bufor, tworzony jest podczas buildu
  • /.git - katalog gita
  • /node_modules - pakiety NodeJS, można go w przypadku niektórych problemów skasować (rm -rf node_modules) i zainstalować je na nowo poleceniem npm i
  • /public - powstaje dopiero w procesie buildu, automatycznie; zawiera statyczny, wygenerowany przez Gatsby'ego build, można go bez strat skasować i wygenerować nowy build (gatsby -clean && gatsby -build)
  • /src - oprócz plików konfiguracyjnych w katalogu głównym, jedyny katalog, w którym mamy coś do zrobienia, to tu powstaje strona.
    • /components - komponenty, czyli powtarzalne elementy strony: np. layout.js
    • /images - pliki, może być /assets szczególnie jeśli mamy kilka rodzajów mediów: obrazki, pliki dźwiękowe, svg...
    • /pages - podstrony - jest to jedyny katalog w /src, którego obecność i nazwa jest obligatoryjna, używanie i nazwy pozostałych katalogów to konwencja
    • /styles - CSS jeżeli potrzebujemy osobnego katalogu dla stylów
    • /templates - szablony stron generowanych programistycznie
  • gatsby-browser.js - opcjonalny; globalny wrapper dla komponentów Gatsby Browser APIs
  • gatsby-config.js - plik konfiguracyjny Gatsby Config API
  • gatsby-node.js - opcjonalny; programistyczne tworzenie stron Gatsby Node APIs
  • gatsby-ssr.js - opcjonalny; jeżeli używamy SSR Gatsby Server Rendering APIs
  • .gitignore - plik gita Git - gitignore Documentation
  • log.md - to moja propozycja, notatnik wszystkich ważnych działań administracyjnych, trzeba dodać do gitignora
  • package.json - informacja dla npm-a jakie moduły są zainstalowane, raczej nie zmieniać, czasem trzeba dokonać zmian w ograniczeniach update, powinniśmy zadbać o archiwizację, (najlepsza jest ta na GitHubie) package.json
  • package-lock.json - kompletne info dla npm, nie do edycji package-lock.json

Na tę chwilę sytuacja jest dużo prostsza i przedstawia się następująco:

  • /.git
  • /node_modules
  • /src
    • /pages - tu będziemy tworzyć stronę
  • gatsby-config.js
  • .gitignore
  • package.json
  • package-lock.json

Komponenty stron

W katalogu /src tworzymy katalog pages (obie nazwy są obowiązkowe), w którym znajdują się pliki strony, to właśnie tam Gatsby szuka pliku index.js, który jest domyślnym plikiem strony głównej. Inaczej mówiąc - wszystkie elementy stron w Gatsbym to komponenty Reacta, a te które znajdują się w katalogu /src/pages automatycznie traktowane są jako strony i dla nich rysowane są ścieżki tworzone na podstawie ich nazwy. Więcej: Building with Components

Schematycznie zawartość plików stron w /src/pages/ wygląda tak:

import React from 'react';

const NazwaPodstrony = () => {
  return (
      ... treść strony w JSX
  )}
  
export default NazwaPodstrony

Jak widać, jest to typowy komponent Reacta:

  • zaczyna się od importów
  • potem jest przypisanie funkcji strzałkowej z treścią komponentu w returnie
  • na końcu jego eksport

Nie powinna to być anonimowa funkcja. Gatsby traktuje to jako błąd, nie wywala to strony, ale dostajemy zgłoszenie błędu. Treść to znany z Reacta JSX.

Poniżej najprostszy przykład strony Gatsby'ego.

/src/pages/index.js

import * as React from 'react'

const IndexPage = () => {
    return (
        <h1>Hello World!</h1>
    )
}

export default IndexPage

React Fragments

Oprócz pliku index.js, wymagany jest domyślny 404.

Trzeba pamiętać, że tak jak każdy komponent Reacta, treść strony musi być zawarta w jednym obejmującym wszystko tagu. Jeżeli nie chcemy dokładać kolejnego znacznika, możemy zastosować React Fragments (Fragments). Według tego schematu przykładowa strona 404 z React Fragment:

/src/pages/404.js

import React from 'react';

const PageNotFound = () => {
    return (
        <>
            <h1>404</h1>
            <p>Strona, której szukasz nie została znaleziona</p>
        </>
    )
}

export default PageNotFound

Podstawowym narzędziem nawigacji znanym z Reacta są komponenty Link i NavLink. W Gatsbym mamy tylko ten pierwszy, ale ma on właściwości obydwu: Gatsby Link API. Używamy go do linków wewnętrznych strony. Do linków zewnętrznych oraz kotwic wewnątrz podstrony używamy zwykłych odnośników.

Stosowanie komponentu Link oprócz wewnętrznej optymalizacji zapewnia dwie rzeczy:

  • ładowanie nowej treści bez przeładowywania strony
  • możliwość znana z komponentu Reacta NavLink, można dodać do Link parametr activeClassName="active" definiujący nazwę klasy automatycznie nadawanej aktywnym linkom.

/src/pages/about.js

import * as React from "react"
import { Link } from "gatsby"

const AboutPage = () => {
  return (
    <>
      <Link to="/">Strona główna<Link>
      <h2>About</h2>
      <p>Treść podstrony About</p>
    </>
  )}

export default PageNotFound

Punktem odniesienia jest katalog stron, czyli /src/pages. Więc analogicznie, link to strony About, jeżeli plik jest zatytułowany about.js, będzie /about, a do 404.js /404.

Teraz już możemy uruchomić środowisko deweloperskie poleceniem gatsby develop i jak zakończy się powodzeniem zobaczyć stronę pod adresem localhost:8000.

Podsumowanie

To tyle na teraz! Możesz też zrobić builda poleceniem gatsby build, jak zakończy to gatsby serve i możesz zobaczyć stronę pod adresem localhost:9000.

Tematem następnego wpisu będzie zbudowanie strony przy użyciu komponentów, przede wszystkim komponentu layout.js.