JAMstack: створюємо блог з Gatsby + Contentful + Netlify

Ви вже чули про новий підхід JAMstack? Нарешті з’явилася можливість створювати веб-додатки на улюбленому React, мати зручну адмінпанель для керування контентом, а на виході отримувати повністю валідні HTML-сторінки, побудовані згідно з останніми рекомендаціями SEO, PWA та a11y.

Цікаво? Тоді ось список тем, розглянутих у статті:

  • Що це за новий стек і навіщо він потрібен?
  • Як запустити перший проект на Gatsby?
  • Contentful для керування даними.
  • Як зв’язати Contentful з Gatsby, використовуючи GraphQL?
  • Налаштування автоматичного деплойменту з Netlify.

JAMstack

Як відомо: «Все нове, то давно забуте старе», і ось ще одне підтвердження ― статичні сайти повертаються. Що таке web десять років тому? Це був PHP сервер-рендер, який при кожному запиті з клієнта підставляв дані з БД у HTML-шаблони і віддавав сторінку.

На зміну цьому підходу прийшли JavaScript-фреймворки, які в останні роки представлені святою трійцею вебу React, Angular, Vue, амінь. У чому була кардинальна відмінність? У швидкості і чутливості інтерфейсу, адже тепер вся логіка сайту перебудовується на клієнті. І на будь-який рух мишею можна викликати красиву анімацію з одночасною зміною контенту та відправкою запитів на сервер.

Що далі? JAM пропонує:

  • ніякого server-side рендерингу, та й взагалі прибрати сервер;
  • ніякого client-side рендерингу, ніякого більше <div id ="root"></div>;
  • компілювати сайт у звичайний HTML код один раз, лише в момент зміни контенту;
  • розміщення сайту на будь-якому файловому хостингу.

Клієнт завжди отримує заздалегідь відрендерену сторінку з повністю валідною з точки зору SEO структурою. І продуктивність тепер залежить лише від швидкості інтернет-з’єднання клієнта (але, звичайно ж, не варто забувати про те, наскільки прямі руки в розробників).

Інструменти

JAM — це лише підхід, засобів для якого на ринку вже достатньо. Як відомо, цвяхи можна забивати чим завгодно, але я пропоную використовувати молоток.


Список найкращих інструментів на 2019 рік:

Gatsby ― це генератор статичних сайтів з React + GraphQL додатків. Чому саме такий вибір, а не Angular або Vue, я не знаю. Найімовірніше справа у статистиці, яка говорить, що незважаючи на всі суперечки, React — найпопулярніший фреймворк останніх трьох років (не закидайте мене камінням в коментарях за це твердження, насправді мені заплатили). Для більш наочного уявлення: create-react-app компілює код в JavaScript білд для подальшого рендеру під час старту сторінки. Gatsby генерує повноцінні HTML-сторінки, які показуються як є, навіть з вимкненим JS.

Contentful ― система управління контентом на статичних сторінках. Це WordPress, який не зберігає зв’язки між шаблонами і даними в БД, а замість цього змінює дані безпосередньо в HTML-файлах.

Netlify ― це дуже проста у використанні система деплойменту, яка дозволяє зв’язати більшість популярних файлових хостингів з JAM додатком та ще й на HTTPS-протоколі.

До справи

Тепер, коли визначилися з інструментами, можна починати.

Contentful

Створюємо аккаунт і бачимо, що автоматично сервіс генерує зразковий проект, який я рекомендую відразу ж видаляти. На мою суб’єктивну думку, він більше заважає, аніж допомагає розібратися. Створюємо новий безкоштовний проект, без генерації зразків.

У цілому система управління базується на двох сутностях — Content model, що описує структуру і типи даних, і сам Content. Для початку створимо просту модель для нашого блогу. Content model складається з типів даних, наприклад, для блогу типами даних будуть: Article, Person.

Звичайно ж, можна вибрати рівень абстракції, який здається кращим. Наприклад, можна замість Person вказувати дані про автора всередині Article, як Article.author_name

Зразок структури даних
  article/
  ├── title (Short text)
  ├── text (Long text)
  ├── banner (Single media)
  └── publishedAt (Date & Time)

  person/
  ├── fullName (Short text)
  └── avatar (Single media)

Далі, використовуючи вже створені типи даних, додаємо контент. Для текстів можна використовувати SaganIpsum, для зображень — Unsplash.

Gatsby

Відкриваємо термінал і створюємо робоче середовище:

## Встановлення
npm install --global gatsby-cli

## Створення проекту
gatsby new personal-blog

## Для любителів мінімалізму можна встановити Hello World проект
## gatsby new minimal-gatsby https://github.com/gatsbyjs/gatsby-starter-hello-world

## Переходимо в теку
cd personal-blog

Структура згенерованого проекту

## Запуск проекту с hot-reloading
gatsby develop

Що вийшло? React + GraphQL додаток, який збирається за допомогою Gatsby. Це означає, що можна будь-який старий проект, який довго рендериться, перевести в статичний HTML-сайт і отримати приріст у швидкості в кілька разів.

Gatsby+Contentful

## Встановлення додаткових пакетів
npm install gatsby-source-contentful dotenv

Створюємо файл .env в кореневій теці додатку з таким змістом:

/* 12-и значный ключ з Contentful → Settings → API keys → Example key 1→ Space ID */
CONTENTFUL_SPACE_ID=xxxxxxxxxxxx
/* 64-х значный ключ з Contentful → Settings → API keys → Example key 1→ Content Delivery API - access token */
CONTENTFUL_ACCESS_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Розширюємо конфігурацію в gatsby-config.js:

if (process.env.NODE_ENV === "development") {
  require("dotenv").config();
}
module.exports = {
  /* other settings */
  plugins: [
    /* other plugins */
    {
      resolve: `gatsby-source-contentful`,
      options: {
        spaceId: process.env.CONTENTFUL_SPACE_ID,
        accessToken: process.env.CONTENTFUL_ACCESS_TOKEN,
      },
    }
  ]
}

Перезапускаємо Gatsby сервер, і, якщо консоль не має ніяких помилок, значить з’єднання з Contentful встановлено і можна переходити далі.

Gatsby+GraphQL+Contentful

Якщо ви ще не знайомі з GraphQL, то не переймайтесь, бо це досить просто. Сайт зараз знаходиться за адресою:

http://localhost:8000

Але поки що залишимо його і відкриємо другу вкладку:

localhost:8000/___graphql

Перед нами IDE для GraphQL прямо в браузері. З ним дуже зручно будувати запити і тестувати їх. Натисніть на Docs у верхньому правому куті, щоб розгорнути сайдбар з документацією. Але сюрприз, це не документація до GraphQL, це документація вашого API. Розгорніть список Query, щоб побачити всі доступні схеми для запитів, з їхніми типами даних.

Схеми, які нас цікавлять, мають приблизно такі назви:

  • contentfulВашТипДаних — один екземпляр
  • allContentfulВашТипДаних — список з екземплярів

Зразок моїх даних
  • contentfulArticle
  • contentfulPerson
  • allContentfulArticle
  • allContentfulPerson

Використовуючи ліву панель, побудуємо правильний запит для наших даних (спробуйте автодоповнення, дуже зручно).

Зразок, який запитує один екземпляр типу Person та список з Article
  {
    contentfulPerson {
      fullName
      avatar {
        file {
          url
        }
      }
    } 
    allContentfulArticle {
      edges {
        node {
          title
          text {
            text
          }
          banner {
            file {
              url
            }
          }
          publishedAt
        }
      }
    }
  }

Що можна відзначити зі структури запитів:

  • щоб отримати URL для файлу, потрібно звертати на шлях typeName.file.url;
  • щоб отримати текст з типу Long text, йдемо по шляху typeName.typeName;
  • щоб отримати список екземплярів якогось типу, потрібно використовувати шлях allContentfulName.edges.

Переносимо схему запиту до проекту і рендеримо відповідь як звичайні дані в React-додатку. Загальноприйнятим Best Practice вважається використання <StaticQuery /> компонента, з пакета gatsby, який вже встановлений в проект.

Зразок файлу index.js
  import React from "react"
  import { StaticQuery, graphql } from "gatsby"

  import Layout from "../components/layout"
  import Article from "../components/article"

  const IndexPage = () => (
    <Layout>
      <StaticQuery
        query={graphql`
          {
            allContentfulArticle {
              edges {
                node {
                  id
                  title
                  text {
                    text
                  }
                  banner {
                    file {
                      url
                    }
                  }
                  publishedAt
                }
              }
            }
          }
        `}
        render={({
          allContentfulArticle: {
            edges
          }
        }) => (
          edges.map(({ node }) => (
            <Article key={node.id} content={node} />
          ))
        )}
      />
    </Layout>
  )

  export default IndexPage

Як це працює? Вquery передається схема запиту GraphQL, а в render — наш улюблений JSX. Використовуйте деструктуризацію, щоб зробити код більш читабельним.

Зразок деструктуризації на прикладі components/article.js
  import React from "react"

  const Article = ({
    content: {
      title,
      text,
      banner: {
        file: {
          url
        }
      },
      publishedAt
    }
  }) => (
    <div>
      <h2>{title}</h2>
      <img src={url} alt={title}/>
      <p>
        {text}
      </p>
      <h5>{publishedAt}</h5>
    </div>
  )

  export default Article

Тепер, коли стало зрозуміло, як отримати і відрендерити дані, можна починати розробку. Але оскільки ця стаття не про те, «як зробити сайт на реакті», то ми пропустимо цей момент і уявимо, що сайт вже готовий.

Розмістимо наш проект на GitHub, звідки його можна буде публікувати в наступному кроці.

Для тих, хто досі не в курсі, як це зробити
  ## Находясь в папке с проектом инициализируем пустой репозиторий
  git init

  ## Сделаем первый коммит
  git add .
  git commit -m “initial commit”

  ## Создаем репозиторий на GitHub и подключаем
  git remote add origin 
 Данный адрес e-mail защищен от спам-ботов, Вам необходимо включить Javascript для его просмотра.
 :yourname/my-repository-name.git

  ## Публикуем изменения
  git push origin master

Налаштовуємо Netlify

Створюємо аккаунт, використовуючи той сервіс, на якому планується розміщення проектів. Я вибрав GitHub, тому після успішної авторизації налаштуємо новий проект з New site from Git. Підключаємо наш репозиторій, а Netlify автоматично визначить, що це Gatsby проект, і налаштує всі скрипти для збірки.

Вибираємо потрібну гілку і не забуваємо про змінні оточення. Для цього відкриваємо меню Advanced settings і додаємо змінні з локального файлу .env та підтверджуємо налаштування.

Кілька хвилин магії, і сайт на місці: https://tender-liskov-ce3ad0.netlify.com

Залишилося додати хук на оновлення контенту. Переходимо в налаштування:

Deploy settings → Build hooks → Add build hook

Встановлюємо будь-яку зрозумілу назву, для прикладу «Contentful hook», вибираємо гілку, з якої будемо робити білд, і підтверджуємо. Результатом буде посилання, копіюємо його і переходимо в панель Contentful:

Settings → Webhooks

Шукаємо на правій панелі темплейт для Netlify і за кілька кліків пов’язуємо дві системи. Пробуємо змінити контент і дивимося, як нові дані з’являються на сайті.

Висновок

JAM-stack поєднує в собі рішення проблем попередніх підходів і, схоже, претендує на захоплення влади і всесвітню популярність. Але чи це революція? Нічого нового і особливого немає, але це найбільш передова методологія останніх двох років там, на чужині, а у нас? Ми тільки-тільки почали переводити проекти з WordPress на React, і це однозначно прогрес. Але, може, щоб не залишитися за бортом, як легендарний індійський аутсорс, нам час робити більш рішучі кроки?

Репозиторій з проектом


Читайте також:

Фишки JAMstack: почему статические сайты превосходят традиционные динамические

Похожие статьи:
[Об авторе: Андрей Пивоваров — CEO образовательного проекта GoIT] Мы не случайно родились в Украине. Я считаю, что вместо того, чтобы...
Я работаю программистом уже более 13 лет: занимаюсь высоконагруженными и распределенными системами, рассматриваю и оцениваю...
The big day has arrived when you will be moving home. It is a stressful occasion, so you may be worried about what to expect on the day of your move. Here’s how your moving day might unfold, with thanks to Mod24, who...
Savvy IT School приглашает на курсы для начинающих программистов по специальности QA Engineer. Для кого эта программа? Для начинающих...
Усім привіт! Мене звати Олексій Остапов, я понад 12 років працюю в IT, у компанії Infopulse, займаюся тестуванням, автоматизацією,...
Яндекс.Метрика