Рендеринг HTML - это один из вариантов использования Serverless, который я впервые попробовал. Мне нравится идея:

  1. Одна функция (бессерверная)
  2. Рендеринг компонентов React (рендеринг на стороне сервера)
  3. В конечной точке HTTP (состав микросервисов)
  4. Возврат полноценного приложения / страниц. (одностраничные приложения)

Преимущества каждого из отмеченных комментариев хорошо документированы в Интернете. От SSR, обеспечивающего лучшее SEO и более быстрое реагирование на мобильные устройства, и микросервисов, определяющих сегодня большинство инфраструктур крупных компаний, и постоянно сложных SPA, использующих наши любимые приложения для социальных сетей и онлайн-инструментов для совместной работы, и потрясающий потенциал Serverless для экономии средств и бесконечной масштабируемости.

Давайте попробуем собрать простой пример того, как достичь их всех в одном SPA, написанном на React, развернутом в Google Cloud Functions.

Бессерверная функция

Начнем с простой функции Google Cloud.

$ mkdir my-serverless-app
$ cd my-serverless-app
$ npm init -y

Давайте добавим код в index.js:

И новое значение в разделе сценария package.json:

"scripts": {
  "deploy": "gcloud beta functions deploy my-serverless-app-1_0_0 --entry-point handler --trigger-http --stage-bucket medium-post-functions --memory=2048MB"
},

Как только у нас будет эта пара частей, мы можем просто сделать:

$ yarn deploy

И наблюдайте за развертыванием нашего ЗКФ. Обратите внимание, что я использовал 2048 МБ памяти. (не стесняйтесь изменить это позже). На данный момент у нас есть конечная точка HTTP, возвращающая статический контент.

Реагирование с рендерингом на стороне сервера

Создание еще одной реализации SSR для React на данный момент не очень продуктивно. Уже есть много хороших реализаций этого. Плюс хороший набор библиотек для ускорения разработки на React.

  • create-response-app (https://www.npmjs.com/package/create-react-app) Решает множество проблем при запуске с React, но не с SSR.
  • nwb (https://www.npmjs.com/package/nwb) Аналогично create-response-app, но с поддержкой Preact, Inferno, библиотеки компонентов и т. д.
  • react-cdk (https://github.com/storybooks/react-cdk) Мне понравилось, Storybooks - отличный способ создавать библиотеки компонентов с интерактивными руководствами по стилю.
  • razzle (https://www.npmjs.com/package/razzle) Хорошая библиотека, поддерживает SSR. +1 за использование реактивного маршрутизатора v4.
  • next (https://www.npmjs.com/package/next) Вероятно, самая полнофункциональная библиотека React на данный момент. Является ли SSR и его папка с примерами чистым золотом JS. ;)

Итак, я буду использовать Nextjs. Лучший способ научиться им пользоваться - это https://learnnextjs.com/ (я сделал это, мне потребовалось ~ 20 минут, чтобы понять основы). Продолжая работу с тем же репо, давайте сначала добавим зависимости Nextjs.

$ yarn add react react-dom next
$ mkdir pages

И давайте сделаем pages / index.js как корень нашего приложения.

И небольшое дополнение к package.json:

{
  "scripts": {
    "dev": "next"
  }
}

Итак, теперь мы можем:

$ yarn dev
DONE  Compiled successfully in 3775ms                                                                                                                             > Ready on http://localhost:3000

Перейдите на http: // localhost: 3000 и посмотрите наше Приложение

Приятно, но не особо подходит для рендеринга на стороне сервера или облачных функций Google. Нам нужно создать наше приложение и обслуживать его с помощью функции-обработчика. Nextjs рекомендует сделать это путем создания настраиваемого сервера (https://learnnextjs.com/basics/server-side-support-for-clean-urls/create-a-custom- сервер )

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

А также добавьте еще один скрипт в package.json, чтобы превратить наше приложение в развертываемый вариант (по умолчанию созданное приложение хранится в папке .next, проверьте это)

{
  "scripts": {
    "build": "next build"
  }
}

Наконец-то:

$ yarn build
$ yarn deploy
....
httpsTrigger:
  url: https://us-central1-revelatio-165320.cloudfunctions.net/my-serverless-app-1_0_0
....

Мы можем увидеть наше приложение реагирования на рендеринг конечной точки, если зайдем по адресу: «https://us-central1-revelatio-165320.cloudfunctions.net/my-serverless-app-1_0_0 жен/

Обратите внимание на завершающую косую черту (/) в конце нашего вызова конечной точки. Кажется, есть пара ошибок из GCF и Nextjs заканчивается. GCF предполагает, что маршрут по умолчанию - пустая строка, поэтому

https://us-central1-revelatio-165320.cloudfunctions.net/my-serverless-app-1_0_0
req.url === ''
https://us-central1-revelatio-165320.cloudfunctions.net/my-serverless-app-1_0_0/
req.url === '/'

И Nextjs не работает, если путь пуст. Эта маленькая причуда ломает конечную точку без косой черты в конце. Более надежной версией нашей функции-обработчика может быть:

После повторного развертывания мы можем безопасно получить доступ к нашей конечной точке HTTP без косой черты в конце. Рендеринг на стороне сервера FTW.

Состав микросервисов

Все нормально со стороны ССР. Но наше приложение не работает на стороне клиента.

Ресурсы нашего приложения не загружаются из GCF. Эти ресурсы включают в себя практически все активы приложения, такие как пакеты Javascript, CSS и изображения (если есть). Nextjs использует абсолютные маршруты для получения ресурсов и обработки маршрутизации. Нам нужно обслуживать наше приложение по базовому корневому пути домена или /.

Простой способ сделать это - использовать NGINX:

http {
  upstream app_server {
    server us-central1-revelatio-165320.cloudfunctions.net;
  }
  server {
    listen       80;
    server_name  www.mi-app.com;
location / {
      proxy_pass   https://app_server/my-serverless-app-1_0_0;
      proxy_redirect off;
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
    }
  }
}

NGINX - хорошая, ХОРОШАЯ программа. Но, IMHO истинный бессерверный подход должен стоить ноль (cero) на обслуживание сервера. Итак, давайте выберем другого провайдера, в данном случае Fastly (https://www.fastly.com/).

На Fastly мы можем создать Сервис:

  1. Установите наш собственный домен приложения.
  2. Настройте Host как домен нашей облачной функции, включая поддомен. (Пример: us-central1-revelatio-165320.cloudfunctions.net)
  3. Включите TLS и используйте порт 443
  4. Имя хоста сертификата и имя хоста SNI такое же значение, как # 2
  5. Переопределить хост установлен так же, как # 2
  6. Создайте правило заголовка, чтобы преобразовать свойство req.url из запроса и переписать все URL-адреса с / * на / my-serverless-app-1_0_0 / * (тип: Request / Regex, Destination: url, источник: req.url, регулярное выражение: ^ (. *) $, подстановка: / my-serverless-app- 1_0_0 \ 1)

Конечно, Fastly требует, чтобы вы добавили реестр CNAME в DNS вашего домена для правильной работы.

После того, как все эти настройки установлены (мне потребовалось 6 версий, чтобы все было правильно), вы можете развернуть свое приложение на GCF, маршрутизируемом через очень производительный кеш и глобальный CDN.

Другие облачные функции Google, такие как серверные части API, могут быть развернуты с использованием того же подхода, конечно, на разных маршрутах. / api / v1 или / api / graphql.

(Узнайте, как сделать простой бэкэнд mongoDB на GCF «https://medium.com/google-cloud/creating-a-mongodb-crud-backend-on-google-cloud-functions-88bb5c1cef77 имеет )

Одностраничные приложения

На данный момент этот пост становится слишком длинным. Итак, перейдите на https://learnnextjs.com и https://github.com/zeit/next.js/tree/v3-beta/examples и создайте отличные приложения.

Правка 1: Немного изменен пример восходящего потока NGINX. Я не полностью протестировал этот подход, я бы порекомендовал вам использовать Kong API Gateway (https://getkong.org).