Но, надеюсь, будет полезно и другим.

Это сборник документации, объяснений и советов по Next.js. С несколькими фрагментами кода и изображениями в помощь.

Основное внимание уделяется тому, как «серверная сторона» работает в Next.js. Спойлер - он может больше, чем просто отображать HTML

В настоящее время последняя версия Next.js - 9.5.

Что такое Next.js?

Это платформа для создания приложений React, отображаемых на стороне сервера.

Но Next.js предназначен не только для создания внешнего интерфейса приложения, поскольку он «серверный», его также можно использовать для создания полного внутреннего интерфейса для приложения.

Как работает серверная часть?

«Серверную» в приложениях Next.js можно разделить на две части:

  1. Рендеринг на стороне сервера - как Next.js генерирует HTML на стороне сервера и отправляет его клиенту.
  2. Внутренний сервер - как Next.js поддерживает внутренний сервер и API

Рендеринг на стороне сервера (предварительный рендеринг)

Предварительный рендеринг = общий термин для рендеринга HTML перед его отправкой клиенту

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

  1. Статическая генерация
  2. Серверный рендеринг (SSR)

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

Статическая генерация означает, что HTML-код создается один раз на сервере во время сборки, и этот HTML-код повторно используется для каждого клиентского запроса.

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

Это может быть приемлемо, когда извлекаемые данные не часто меняются и / или в сценариях, где пользователю не всегда нужны самые обновленные данные. Но часто очень важно, чтобы пользователю было показано текущее представление данных, а это означает, что статическая генерация страниц не может использоваться.

Отображение на стороне сервера (SSR) означает, что HTML-код создается на сервере при каждом запросе страницы. HTML-код является «динамическим», а не «статическим», поскольку он будет зависеть от требуемых данных.

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

Next.js предлагает два метода выборки данных для SSR - getServerSideProps и getInitialProp, которые обсуждаются в разделе «Получение данных на стороне сервера» ниже.

Внутренний сервер‌

Бэкэнд-часть приложения Next.js (при условии, что оно вам нужно) может быть построена двумя способами:

  1. Использование собственного сервера
  2. Использование бессерверных маршрутов API‌

Пользовательский сервер - это обычный сервер NodeJS, который можно создать с использованием выбранной вами платформы и библиотек, обычно Express.

Сервер должен возвращать статические ресурсы для каждого маршрута внешнего интерфейса в приложении (с использованием функции Next.js getRequestHandler), но кроме этого сервер может вести себя как любой другой с промежуточным программным обеспечением, маршрутами API, подключением к базе данных и т. Д.

Маршруты API - это встроенные функции Next.js для написания серверных API. Каждая функция является обработчиком запросов, написанным с использованием «методов, подобных Express.js», и будет развернута как бессерверная функция.

(req, res) => { // send back some json }

Маршруты API используют маршрутизацию файловой системы - любой файл в каталоге /pages/api/ будет развернут как конечная точка API. Например, обработчик функции в /pages/api/users.js будет доступен для запросов в https://your-domain.com/api/users

Также поддерживается динамическая маршрутизация, позволяющая использовать параметры запроса URL. Например, обработчик в /pages/api/users/[userId].js будет иметь доступ к req.query.userId

‌ Наконец, маршруты для приема всей почты домена также возможны как /pages/api/[...rest].js (где 'rest' может называться как угодно). Это может быть полезно, если приложение имеет некоторые из собственных API-интерфейсов, но также действует как прокси для внешней серверной службы.

Некоторые из основных различий между маршрутами API и типичным сервером Express / NodeJS можно увидеть в приведенном выше коде:

  1. Подключение к базе данных должно выполняться при запуске каждого обработчика. Здесь функция базы данных connect() фактически сначала проверит, есть ли уже активное соединение, и только если его нет, она попытается подключиться.
  2. Промежуточное ПО представлено в виде функций высшего порядка, которые обертывают и расширяют обработчик - указанная выше функция использует withAuth промежуточное ПО, которое проверяет аутентификацию перед тем, как разрешить обработку запроса.

Какой бэкэнд-подход мне выбрать?

Next.js официально рекомендует использовать API Routes по многим веским причинам, которые объясняются в первоначальном RFC функции.

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

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

Их использование делает создание полностековых приложений невероятно быстрым - создание API не должно занимать больше времени, чем создание компонента React. Это также гарантирует, что ваш бэкэнд является масштабируемым, независимым и производительным.

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

Получение данных на стороне сервера

Next.js поддерживает два типа рендеринга на сервере, как описано выше (статическая генерация и SSR) - какой из них он использует для данной страницы, определяется тем, как эта страница получает данные.

Общее правило: для SSR лучше использовать getServerSideProps вместо getInitialProps, чтобы избежать ситуации, когда выборка данных может происходить как на стороне сервера, так и на стороне клиента.

При начальной загрузке страницы getInitialProps будет выполняться только на сервере. getInitialProps затем будет запускаться на клиенте при переходе к другому маршруту с помощью компонента next/link или с помощью next/router.

Это означает, что ваш getInitialProps код должен быть написан таким образом, чтобы он работал как на стороне клиента, так и на стороне сервера - для перенаправления пользователя может потребоваться ctx.res.writeHead (сервер) или может потребоваться Router.push (клиент).

getServerSideProps имеет тот же эффект, что и getInitialProps, но более предсказуем, потому что он будет работать только на сервере.

Два совета, которые нужно завершить:

  1. Next.js движется быстро - не забудьте заглянуть в их блог, чтобы узнать о последних обновлениях, так как в нем почти всегда есть что-то потрясающее.
  2. Если вы запускаете новое приложение Next.js, загляните в официальный репозиторий примеров, чтобы узнать, есть ли пример настройки для выбранного вами технологического стека (он почти всегда будет).