Этот репо документирует попытку использования Next.js (Сохранение собственных функций SSR) со следующей настройкой:
- Одиночная точка входа (например, создать приложение React и Хмель ) Нет маршрутизации на основе файловой системы React-Router
- как только система маршрутизации
Этот документ доступен как:
- Репозиторий GitHub
- dev.to post
Отказ от ответственности
- Next.js Команда настоятельно рекомендует этому подходу.
- Этот эксперимент был проведен во времена Next.js v9.3: с тех пор структура сильно изменилась.
Часть первая, базовая настройка
1 – Установите Next.js
Соответствующий репомит Анкет
Установите NextJS Как обычно и создать единственная точка входа Файл в Страницы/index.js Анкет
2 – перенаправить все запросы на одну точку входа
Соответствующий репомит Анкет
Чтобы пропустить маршрутизацию на основе файловой системы, мы настроим Пользовательский сервер Next.js пересылать все запросы в нашу единую точку входа.
Мы будем использовать next.js Server.Render метод Чтобы отобрать и обслуживать точку входа.
// server.js
const express = require('express');
const nextJS = require('next');
async function start() {
const dev = process.env.NODE_ENV !== 'production';
const app = nextJS({dev});
const server = express();
await app.prepare();
// Redirect all requests to main entrypoint pages/index.js
server.get('/*', async (req, res, next) => {
try {
app.render(req, res, '/');
} catch (e) {
next(e);
}
});
server.listen(3000, err => {
if (err) throw err;
console.log(`> Ready on http://localhost:3000`);
});
}
start();
Запустите Dev Server и страницу intrypoint по адресу Страницы/index.js должен служить ответом для любого запрошенного URL. 👊
3 – ввести реагируемый маршрут
Соответствующий репомит Анкет
Чтобы получить разные ответы в соответствии с запрошенным URL -адресом, нам нужна система маршрутизации.
Мы будем использовать React-Router (См. Это Документы о SSR ) и оберните приложение StaticRouter или Browserrouter На основе среды приложения среды (сервер или браузер).
Установить React-Router и Реактивная маршрута-дома :
npm i react-router react-router-dom -S
… и обновить Страницы/index.js входная точка, чтобы использовать некоторые Ссылка и Маршрут Компоненты из React-Router-Dom (См. Репо).
Давайте теперь объявим withreactrouter Hoc, чтобы обернуть приложение с помощью надлежащего маршрутизатора:
// next/with-react-router.js
import React from 'react';
import {BrowserRouter} from 'react-router-dom';
const isServer = typeof window === 'undefined';
export default App => {
return class AppWithReactRouter extends React.Component {
render() {
if (isServer) {
const {StaticRouter} = require('react-router');
return (
);
}
return (
);
}
};
};
… и обернуть приложение withreactrouter Hoc:
// pages/_app.js
import App, {Container} from 'next/app';
import React from 'react';
import withReactRouter from '../next/with-react-router';
class MyApp extends App {
render() {
const {Component, pageProps} = this.props;
return (
);
}
}
export default withReactRouter(MyApp);
Запустите Dev Server, и вы сможете увидеть свои маршруты в прямом эфире и отображаются на стороне сервера.
Часть вторая, контекстная информация
Один из моих любимых React-Router Особенности состоит из возможности Добавление контекстной информации На этапе рендеринга и Возвращение ответов на стороне сервера на основе информации, собранной в контекст объект Анкет
Это позволяет коду клиента контролировать ответы, возвращаемые сервером узла, такие как Возвращение http 404 вместо «не найденной страницы» или возврата Real Http 302 перенаправление вместо клиента.
Чтобы достичь такого поведения, мы должны настроить next.js, чтобы сделать следующее:
- Отправить запрошенную страницу, предоставляющую объект контекста для маршрутизатора приложения
- Проверьте, был ли объект контекста мутировал в процессе рендеринга
- Решите, вернуть ли образованная страница или сделать что -то еще на основе объекта контекста
4 – Предоставьте контекст объекта маршрутизатора
Соответствующий репомит Анкет
Мы вводим пустой контекст объект в Express ‘ req.local объект и сделайте его доступным для приложения маршрутизатора через Реагировать контекст Анкет
Давайте вводим контекст объект в Express ‘ req.local объект:
// server.js
server.get('/*', async (req, res, next) => {
try {
+ req.locals = {};
+ req.locals.context = {};
app.render(req, res, '/');
Next.js предоставляет req и res Объекты как реквизиты GetInitialProps Статический метод . Мы возьмем req.originalurl и req.locals.context и обрабатывать его к статическому маршрутизатору.
// next/with-react-router.js
return class AppWithReactRouter extends React.Component {
+ static async getInitialProps(appContext) {
+ const {
+ ctx: {
+ req: {
+ originalUrl,
+ locals = {},
+ },
+ },
+ } = appContext;
+ return {
+ originalUrl,
+ context: locals.context || {},
+ };
+ }
// Code omitted
5 – Отдельный рендеринг и ответ
Соответствующий репомит Анкет
Поскольку мы хотим предоставить дополнительное поведение сервера на основе req.locals.context промежуточный ответ SSR и сервера, Next.js Server.Render не хватает гибкости.
Мы переосмыслим Server.Render в Server.js с использованием Next.js Server.rendertohtml и Server.sendhtml методы
Обратите внимание, что какой -то код был опущен. Обратитесь к исходному коду для полной реализации.
// server.js
server.get('/*', async (req, res, next) => {
try {
+ // Code omitted
req.locals = {};
req.locals.context = {};
- app.render(req, res, '/');
+ const html = await app.renderToHTML(req, res, '/', {});
+
+ // Handle client redirects
+ const context = req.locals.context;
+ if (context.url) {
+ return res.redirect(context.url)
+ }
+
+ // Handle client response statuses
+ if (context.status) {
+ return res.status(context.status).send();
+ }
+
+ // Code omitted
+ app.sendHTML(req, res, html);
} catch (e) {
Перед отправкой ответа с рендерированным HTML клиенту теперь мы проверяем контекст Объект и перенаправить или вернуть пользовательский HTTP -код, если это необходимо.
Чтобы попробовать это, обновите Страницы/index.js входная точка в Используйте и Компоненты и запустите Dev Server.
Резюме
Мы показали, как можно настроить следующую. Преимущество React-Router , включение Одиночная точка входа подход и полностью Сохранение SSR Анкет
Для этого мы:
- Перенаправил все запросы сервера на Одиночная точка входа
- Завернут Приложение (с использованием hoc) с правильным
React-Routerмаршрутизатор - Инъекция
reqОбъект сервера сместные жители. Контекстобъект - При условии Hoc warpper с
req.locals.contextиreq.originalurl - Распространен Next.js
Server.Renderучитыватьreq.locals.contextПеред отправкой HTML
Переосмысление Server.Render В пользовательском коде – самая тревожная часть, но он может быть сделан ненужным, продлив немного Server.Render API в next.js.
Полученные результаты
Реактивная маршрутизаторная сторона сервера
React-Router’s <Маршрут> Компоненты получают Статически отображается на сервере на основе полученного req.originalurl URL
Http 302 перенаправление, вызванное клиентским кодом
Когда встречи с процессом рендеринга сервера Компонент, ответ сервера вернет Http 302 Ответ с ожидаемым Место Заголовок Анкет
HTTP 404, запускаемый клиентским кодом
Когда встречи с процессом рендеринга сервера компонент, сервер Ответ возвращает Http -ответ с Ожидаемый код статуса Анкет
Дальнейшее рассмотрение
Я уверен, что эта установка далеко не оптимальная. Я буду счастлив принять во внимание любые предложения, отзывы, улучшения, идеи.
вопросы
- Статические страницы не экспортируются
- Режим разработчика не может создать запрошенный маршрут по требованию
GetInitialPropsне реализованы
Оригинал: “https://dev.to/toomuchdesign/next-js-react-router-2kl8”