В этом руководстве, состоящем из трех частей, мы покажем вам, как приступить к работе с прогрессивным веб-приложением (PWA), в котором используется мощный шаблон веб-архитектуры, называемый JAMstack. Мы начнем инициализацию проекта с линтинга и форматирования кода, создания пользовательского интерфейса нашего приложения и, наконец, развернем его в Интернете.

В этом руководстве предполагается, что у вас есть хотя бы некоторый опыт работы с React.js. Однако не бойтесь следовать за вами, если вы никогда раньше не использовали React. Я просто не буду вдаваться в подробности кода, специфичного для React.

Вы можете найти репозиторий для Части 1 здесь. Если у вас есть какие-либо проблемы или вопросы, задайте вопрос, и мы свяжемся с вами в ближайшее время.

Что такое JAMstack?

Как определено на jamstack.org:

`JAMstack`: существительное \ 'jam-stak' \

Современная архитектура веб-разработки, основанная на клиентском JavaScript, многоразовых API и предварительно созданной разметке.

Перефразируя: JAMstack - это способ создания архитектуры ваших веб-приложений с тремя ключевыми принципами:

1. Клиентский javascript обрабатывает всю выборку данных.

2. API-интерфейсы, от которых зависят клиенты, такие как любые базы данных, службы аутентификации, CDN ресурсов и т. Д., Абстрагируются в микросервисы с поддержкой CORS для доступа со стороны клиента.

3. Разметка предварительно отрисовывается во время времени сборки, хотя и не требуется, обычно выполняется с помощью генератора статических сайтов.

Классная история. Но почему?

Производительность

Поскольку разметка отображается во время сборки, серверная среда выполнения для создания разметки отсутствует. HTML-файлы уже готовы к отправке клиенту. Конечно, прирост производительности здесь не является революционным, поскольку в большинстве реализаций веб-серверов используется кэширование страниц, но любое увеличение времени до первого байта является плюсом.

Стоимость

Опять же, поскольку серверной среды выполнения нет, а все, что обслуживается, - это некоторые статические ресурсы, активы могут храниться и обслуживаться из CDN. Это означает, что затраты на развертывание вашего сайта низкие, а некоторые службы, такие как Netlify (о которых мы поговорим позже), могут быть даже бесплатными.

SEO

Вообще говоря, вы хотите, чтобы поисковые роботы выполняли максимально простую работу по индексации вашего сайта. Среди прочего, именно поэтому реализация рендеринга на стороне сервера или предварительного рендеринга в вашем одностраничном приложении является плюсом. Таким образом, поисковым роботам не нужно ждать, пока javascript будет проанализирован и запущен, прежде чем можно будет проиндексировать разметку, разметка уже будет существовать внутри файла HTML. Это не означает, что SPA не сканируются поисковыми системами, однако есть крайние случаи, которые затрудняют это.

Опыт разработчика

Поскольку серверные службы абстрагируются в их собственные API-интерфейсы, интерфейсный инженер может свободно распоряжаться инструментами, библиотеками, фреймворками и языками для использования во внешнем интерфейсе. Нет никаких ограничений на то, какие предварительно обработанные языки или инструменты сборки могут использоваться, как в случае с некоторыми веб-фреймворками. Лично я считаю, что инструменты, разработанные сообществом Node.js, не имеют себе равных, когда дело касается DX. Такие инструменты, как Webpack, позволяют использовать такие функции, как Горячая замена модулей. Я знаю и люблю рабочий процесс разработки, который могут предложить проекты Node.js, и часто испытываю тоску по этим инструментам при работе над проектами с использованием того, что я считаю неполноценным инструментарием разработки.

О приложении, которое мы создаем

Мы будем создавать простое прогрессивное веб-приложение для опросов. Прошедшие проверку пользователи смогут создать опрос с некоторыми параметрами, которыми они, в свою очередь, смогут поделиться с помощью сгенерированной ссылки. Пользователи, переходящие по этой ссылке, могут затем выбрать один из вариантов, и их выбор будет отражен в результатах в режиме реального времени.

Интерфейсный стек

  • Gatsby.js: Gatsby использует возможности рендеринга на стороне сервера React.js для создания разметки во время сборки. Хотя он не рассматривается подробно в этом руководстве, он также позволяет разработчикам извлекать данные из любого источника данных и декларативно втягивать эти данные в свои компоненты с помощью GraphQL, чтобы компоненты могли быть гидратированы данными во время сборки. Чтобы лучше понять все возможности Gatsby.js, перейдите по этой ссылке.
  • Firebase firestore: облачная база данных noSQL, которая предоставляет прослушиватели событий для обновлений в реальном времени при изменении данных с помощью интуитивно понятного и простого в использовании веб-SDK.
  • Firebase auth: также входит в веб-SDK Firebase. Firebase auth может использоваться для аутентификации пользователей через OAuth 2. SDK обрабатывает все мельчайшие детали реализации аутентификации OAuth2 за вас.
  • Netlify: Netlify - это глобальная сеть CDN, которая упрощает непрерывное развертывание в несколько щелчков мышью. Развертывание с Netlify так же просто, как и есть.
  • Стилизованные компоненты: решение css-in-js для конкретной реакции. Это лишь одно из многих решений css-in-js. Еще одна заслуживающая упоминания библиотека - Гламурная. Я просто предпочитаю стилизованные компоненты.
  • Красивее: самоуверенный разработчик кода.
  • ESLint: линтинг Javascript.

Все инструменты, используемые в этом руководстве, бесплатны или имеют невероятно большой уровень бесплатного пользования, так что не стесняйтесь следовать им.

Настройка проекта

Давайте начнем! Установите gatsby-cli глобально, затем запустите gatsby new polling-app и инициализируйте git внутри нового каталога.

Gatsby.js требует node v4.0.0 плюс, прежде чем продолжить, проверьте свою версию Node, запустив node -v в выбранном вами терминале. Я бы рекомендовал установить по крайней мере последнюю версию Node LTS, найденную здесь.

npm install --global gatsby-cli && gatsby new polling-app && cd polling-app && git init

Я не буду рассматривать какие-либо рабочие процессы git в этом руководстве, однако в конце части 2 этого руководства мы настроим Netlify с git для непрерывного развертывания.

После установки всех этих зависимостей мы настроим ESLint. Обычно мне нравится устанавливать Airbnb's ESLint config, а затем просто отменять правила, которые мне не нравятся. Установите конфигурацию Airbnb и зависимости друг от друга. Если вы работаете в Linux / OSX, просто скопируйте и вставьте этот скрипт в свой терминал, который находится в каталоге проекта:

(
  export PKG=eslint-config-airbnb;
  npm info "$PKG@latest" peerDependencies --json | command sed 's/[\{\},]//g ; s/: /@/g' | xargs npm install --save-dev "$PKG@latest"
)

Если у вас Windows, перейдите в репозиторий конфигурации Airbnb ESLint, ссылка на который приведена выше, и там будут инструкции по установке этих зависимостей.

Установите другие одноранговые зависимости ESLint, а также красивее:

npm install -D babel-eslint eslint-config-react eslint-config-prettier eslint-plugin-prettier prettier

-D указывает, что это зависимости от разработки.

Добавьте файл .eslintrc в корень вашего проекта и вставьте эти правила. Все, что вам не нравится, можно просто переопределить с помощью правил:

Сделайте то же самое для файла .prettierrc:

Перейдите в свой package.json, замените сценарий format и добавьте lint в свойстве «scripts».

"format": "prettier --write \"src/**/*.{js,jsx}\"",
"lint": "eslint **/*.{js,jsx} --quiet",

флаг - quiet указывает, что нужно сообщать только об ошибках, а не о предупреждениях. Это необязательно.

По умолчанию prettier проверяет наличие файла .prettierrc в корне проекта и использует эти правила. Попробуйте этот формат скрипта!

npm run format

[Необязательно]: для удобства разработки я предлагаю установить плагины для ESLint и Красивее «» для вашей IDE / редактора кода.

Лакомство на Gatsby.js

Структура каталогов

Давайте рассмотрим структуру каталогов, созданную gatsby-cli.

  • ./src/pages/: - обязательный каталог. ./src/pages/index.js соответствует корневому пути веб-сайта. Таким образом, компонент, определенный в index.js, отображается на www.mysite.com/. Единственный другой файл с предопределенным именем - 404.js. Эта страница отображается каждый раз, когда пользователь переходит на несуществующую страницу. Все остальные файлы в этом каталоге имеют имена, соответствующие пути к сайту. ./src/pages/ page-2 .js можно найти в localhost: 8000 / page-2 / . Вложенные пути можно создать, добавив подкаталог внутри ./src/pages/. Например, ./src/pages/polls/ new .js будет сгенерирован как этот маршрут www.mysite.com/polls/ new . На мой взгляд, этот API интуитивно понятен и отлично работает в большинстве случаев.
  • ./src/layouts/: Файлы здесь необязательны, но они имеют определенную цель, определенную Гэтсби. Для простоты в этом руководстве мы рассматриваем только ./src/layouts/index.js. Этот файл окружает все компоненты страницы внутри ./src/pages. Это место для вставки компонентов верхнего и нижнего колонтитула при условии, что все ваши страницы используют этот верхний и нижний колонтитулы.
  • ./src/components/:. Здесь вы размещаете свои пользовательские компоненты, и то, как вы структурируете этот каталог, зависит от вас. Технически, ваши компоненты даже не обязательно должны находиться в этом каталоге, но это обычное соглашение. Я использую этот каталог для своих функциональных компонентов без сохранения состояния.

Плагины

У Gatsby довольно много официальных плагинов и плагинов сообщества, которые упрощают интеграцию многих распространенных инструментов или библиотек. Вы можете найти плагины, которые ищете, и прочитать об их системе плагинов здесь. Один из них - gatsby-plugin-styled-components. Давайте посмотрим, как добавить плагин в проект Gatsby.

Установите gatsby-plugin-styled-components, а также styled-components:

npm install gatsby-plugin-styled-components styled-components

После установки откройте gatsby-config.js в корне вашего проекта. Как видите, у нас уже есть плагин. gatsby-plugin-реагировать-шлем добавляется стартером gatsby-cli по умолчанию. Добавьте gatsby-plugin-styled-components в качестве другого элемента в массив plugins. Пока мы это делаем, обновите siteMetadata.title, указав название нашего сайта; что-то креативное и оригинальное - например, «Приложение для голосования».

Каждый раз, когда вы добавляете плагины, вам, возможно, придется перезапустить сервер разработки.

./gatsby-config.js
module.exports = {
  siteMetadata: {
    title: 'Polling App',
  },
  plugins: [
    'gatsby-plugin-react-helmet',
    'gatsby-plugin-styled-components'
  ],
};

Для этих двух конкретных плагинов порядок не имеет значения. Однако имейте в виду, что есть некоторые плагины, которые необходимо разместить до или после других плагинов. Просто всякий раз, когда добавляете плагин, обязательно прочтите документацию, иначе вы можете столкнуться с неожиданным поведением.

Пачкаем руки

Давайте на самом деле напишем код! Запустите сервер разработки, запустив npm run develop. Затем перейдите по адресу http: // localhost: 8000 /. Мы собираемся создать целевую страницу для нашего сайта. Удалите файл ./ src / pages / page-2.js, если ваша версия gatsby-cli сгенерировала этот файл, и он нам не понадобится. Также удалите компонент ‹Link› и закомментируйте его import (мы будем использовать его позже) , чтобы закрыть ESLint в ./pages/index.js, поскольку страница, на которую он ссылается, больше не существует.

Мы сохраняем ./src/layouts/index.css. Я думаю, что здесь есть несколько разумных сбросов CSS.

Стилизованные компоненты

Затем давайте немного изменим компонент Header.js. Измените заголовок заголовка с Gatsby на заголовок нашего сайта Polling App. Теперь давайте переместим встроенные стили, которые будут обрабатываться styled-components. Теперь ваш заголовочный файл должен выглядеть так:

Здесь следует отметить пару моментов:

1. Странные открывающие и закрывающие обратные галочки (`) после стиля. Это просто шаблонные литералы; да, те же самые, что используются для интерполяции строк, но используются менее известным способом. Он позволяет интерфейсным разработчикам использовать фактические имена свойств CSS, а не их аналоги из camelCase, требуемые javascript.

2. Из-за такого необычного использования шаблонных литералов большинство IDE и редакторов кода не имеют встроенной подсветки синтаксиса для CSS, определенного внутри строк шаблонных литералов. Вот ссылка, где можно проверить, есть ли в вашем любимом редакторе плагин подсветки синтаксиса для стилизованных компонентов.

3. Компонент styled (Link): это функция более высокого порядка, которая передает сгенерированную хешированную опору className в обернутый компонент для стилей. определены в шаблонных литералах. Это может работать с любым сторонним компонентом, если обернутый компонент передает props.className дочернему элементу DOM.

4. Свойство background передается в стилизованный компонент HeaderContainer. Это то, что делает стилизованные компоненты мощными. Он позволяет передавать динамические данные в стили компонентов, обеспечивая гибкость при выборе стиля, которой в противном случае не было бы в обычных файлах CSS.

Следует также отметить, что стилизованный компонент, который мы определили как HeaderWrapper, имеет почти те же стили, что и элемент, обертывающий props.children () внутри ./src/ макеты / index.js. Это возможность сохранить наш код сухим. Создайте каталог с именем styledComponents внутри каталога ./src/. Я придерживаюсь соглашения о стилизованных компонентах: всякий раз, когда у меня есть стилизованный компонент, который можно использовать повторно, я извлекаю его в отдельный файл внутри ./src/styledComponents/.

Поскольку этот стилизованный компонент используется для макета, давайте поместим его в файл с именем layout.js. Я думаю, что подходящее имя для этого конкретного стилизованного компонента - Контейнер. Вырежьте объявление HeaderWrapper и вставьте его в ./src/styledComponents/layout.js, переименуйте его в Контейнер и экспортируйте его:

// ./src/styledComponents/layout.js
import styled from 'styled-components';
export const Container = styled.div`
  margin: 0 auto;
  max-width: 960px;
  padding: 1.45rem 1.0875rem;
`;

Не оборачивайте определенные здесь стилизованные компоненты в функцию, как это можно сделать с функциональным компонентом без состояния в ./src/components/. Вы скоро поймете, почему.

В ./src/components/Header/index.js импортируйте вновь созданный стилизованный компонент Container и замените им стилизованный компонент HeaderWrapper. .

// ./src/components/Header/index.js
import { Container } from '../../styledComponents/layout';
...
const Header = ({ background }) => (
  <HeaderContainer background={background}>
    <Container>
      <Heading1>
        <StyledLink to="/">Polling App</StyledLink>
      </Heading1>
    </Container>
  </HeaderContainer>
);
...

Теперь перейдите к ./src/layouts/index.js и импортируйте стилизованный компонент Container, который мы только что определили из файл stylesComponents / layout.js. Обратите внимание, что ‹div› со встроенными стилями имеет почти те же стили, что и наш компонент Контейнер. разница в том, что он имеет набор правил paddingTop: 0. Однако наш компонент Container определяет padding-top как 1.45rem. Мы заменим этот padding-top с помощью удобного вспомогательного метода, определенного для всех стилей-компонентов .extend. .extend… хорошо расширяет CSS, определенный для компонента, позволяя вам определять базовый набор стилей для компонента, а затем, при необходимости, расширять эти правила.

Вот почему мы не помещаем компонент в каталог ./src/styledComponents с функцией. Это приведет к тому, что все вспомогательные методы больше не будут доступны в компоненте, который мы импортируем.

Пока мы занимаемся этим, давайте добавим скучный цвет фона Header! (Время бесстыдного подключения) - перейдите на www.grabient.com и выберите градиент, не забудьте снять отметку prefixes, так как styled-components уже обрабатывают все префиксы поставщиков. для тебя. Передайте выбранный градиент, который должен быть скопирован в буфер обмена в качестве свойства background, которое мы определили ранее в нашем компоненте Header.

Сбор данных в компоненты с помощью GraphQL

Обратите внимание на свойство title, которое мы передаем в ‹Helmet›, r ecall, что его значение совпадает со значением siteMetadata.title, определенный в ./gatsby-config.js. Давайте повторно используем это значение в качестве заголовка нашего сайта, чтобы, если в будущем мы изменим заголовок нашего PWA, мы должны сделать это только в одном месте. Для этого мы будем использовать функцию gaphql, которую gatsby предоставляет глобально, чтобы разработчики могли декларативно загружать данные в наши компоненты во время сборки. Сегодня мы не будем рассказывать о GraphQL, однако, если вы хотите узнать больше, вот отличный ресурс.

Давайте еще раз обновим файл ./src/layouts/index.js:

обратите внимание, что функция graphql также использует вызовы литералов шаблона для определения запросов и изменений.

Проверьте это! Посмотрите, как Gatsby.js волшебным образом обновляет заголовок сайта, а также Header, когда вы сохраняете ./gatsby-config.js с обновленным заголовком. Подобные вещи - причина, по которой я люблю разрабатывать с Gatsby и другими проектами, использующими Webpack.

Страница указателя

Теперь давайте создадим целевую страницу для нашего приложения для опроса. Мы добавим контент, который действительно будет продавать наше приложение для опросов, в конце концов, оно будет намного лучше, чем все, что уже существует. Также нам понадобится кнопка для создания опроса.

С этого момента я не собираюсь уделять столько внимания styled-components или стилю вообще, я чувствую, что показал вам достаточно, чтобы дать вам представление о том, что styled-components может. Чтобы узнать больше, зайдите на сайт styled-components, который находится здесь.

Добавьте компонент Button в новый файл в ./src/styledComponents/ с именем theme.js:

Я также подозреваю, что мы будем повторно использовать компонент Heading2, расположенный внутри страницы индекса. Давайте создадим файл typography.js внутри ./src/styledComponents/:

Теперь обновите страницу index.js в ./src/pages/:

Страница NewPoll

Давайте продолжим и установим несколько необходимых нам зависимостей.

npm install react-sortable-hoc short-id

Возможно, вам придется перезапустить сервер gatsby после установки этих зависимостей.

Мы будем использовать short-id для генерации идентификаторов для каждой новой добавленной опции и, в конечном итоге, идентификатора для каждого опроса. react-sortable-hoc будет использоваться, чтобы создатель опроса мог изменить порядок своих параметров опроса, если он того пожелает.

Создайте новый файл index.js внутри ./src/components/NewPoll/:

Чтобы все заработало, добавьте страницу new.js в ./src/pages/, которая действует как контейнер для этого компонента.

Перейдите к http: // localhost: 8000 / new, нажав кнопку Новый опрос и ознакомьтесь с функциями новой страницы опроса. На самом деле все, что у нас есть, - это простое приложение с некоторыми клиентскими CRUD-операциями. Но мы действительно продвинулись в направлении конечного продукта!

  • пользователь может создать новый параметр, нажав кнопку добавить или нажав ввод при вводе текста.
  • они могут обновить существующий параметр, дважды щелкнув параметр и отредактировав текст, или изменить его положение, щелкнув, удерживая и перетащив маркер перетаскивания.
  • они могут удалить параметр, нажав x

Если вам понравилось, хлопайте в ладоши!

На этом мы завершаем часть 1 данного руководства. В следующей части мы создадим страницу опроса, настроим аутентификацию Firebase и Firestore, развернем наше приложение с Netlify и, наконец, запустим несколько тестов маяка, чтобы увидеть, как мы оцениваем по шкале от 0 до 100, чтобы определить, что мы создали и считаемся прогрессивным веб-приложением. Все это звучит немного, но я думаю, вы все будете приятно удивлены тем, насколько легко решить эти задачи благодаря инструментам, которые мы используем.

Не забудьте подписаться на нас, чтобы получать больше блогов каждый понедельник и вторник! Мы подготовим для вас Часть 2 в кратчайшие сроки. Увидимся!

Джон Коржук - разработчик программного обеспечения и гордый Unicorn. Он специализируется на полнофункциональном javascript, React.js и веб-разработке. Вне работы его интересы включают игры, киберспорт и изучение всего, что ему интересно. Вы можете найти в твиттере @johnkorzhuk.

Хотите вместе получить волшебный опыт? Связаться с нами!

Электронная почта: [email protected]

Twitter: @UnicornHQ

Сайт: http://www.unicornagency.com