Создание простой архитектуры блога
В нашем примере посты блога будут храниться как локальные markdown-файлы в директории приложения (а не загружаться из внешнего источника данных), поэтому нам нужно будет читать данные из файловой системы.
В этом разделе мы пройдём шаги по созданию блога, который читает markdown-данные из файловой системы.
Создание markdown-файлов
Сначала создайте новую корневую директорию с названием posts
(это не то же самое, что pages/posts
) в корневой папке проекта. Внутри posts
создайте два файла: pre-rendering.md
и ssg-ssr.md
.
Теперь скопируйте следующий код в posts/pre-rendering.md
:
---
title: 'Два вида предварительного рендеринга'
date: '2020-01-01'
---
Next.js поддерживает два вида предварительного рендеринга: **Статическую генерацию (Static Generation)** и **Рендеринг на стороне сервера (Server-side Rendering)**. Разница заключается в том, **когда** генерируется HTML для страницы.
- **Статическая генерация** — это метод предварительного рендеринга, который генерирует HTML во время **сборки**. Затем предварительно отрендеренный HTML _переиспользуется_ при каждом запросе.
- **Рендеринг на стороне сервера** — это метод предварительного рендеринга, который генерирует HTML при **каждом запросе**.
Важно, что Next.js позволяет **выбирать**, какой метод предварительного рендеринга использовать для каждой страницы. Вы можете создать "гибридное" Next.js-приложение, используя статическую генерацию для большинства страниц и рендеринг на стороне сервера для остальных.
Затем скопируйте следующий код в posts/ssg-ssr.md
:
---
title: 'Когда использовать статическую генерацию вместо рендеринга на стороне сервера'
date: '2020-01-02'
---
Мы рекомендуем использовать **статическую генерацию** (с данными и без) везде, где это возможно, потому что ваша страница может быть собрана один раз и обслуживаться через CDN, что делает её намного быстрее, чем если бы сервер рендерил страницу при каждом запросе.
Вы можете использовать статическую генерацию для многих типов страниц, включая:
- Маркетинговые страницы
- Посты блога
- Списки товаров в интернет-магазине
- Справку и документацию
Спросите себя: "Могу ли я предварительно отрендерить эту страницу **до** запроса пользователя?" Если ответ — да, то вам следует выбрать статическую генерацию.
С другой стороны, статическая генерация **не** подходит, если вы не можете предварительно отрендерить страницу до запроса пользователя. Возможно, ваша страница отображает часто обновляемые данные, и её содержимое меняется при каждом запросе.
В таком случае вы можете использовать **рендеринг на стороне сервера**. Он будет медленнее, но предварительно отрендеренная страница всегда будет актуальной. Или вы можете отказаться от предварительного рендеринга и использовать клиентский JavaScript для загрузки данных.
Вы могли заметить, что каждый markdown-файл содержит секцию метаданных вверху с полями
title
иdate
. Это называется YAML Front Matter, и его можно разобрать с помощью библиотеки gray-matter.
Установка gray-matter
Сначала установите gray-matter, которая позволит нам разбирать метаданные в каждом markdown-файле.
npm install gray-matter
Создание вспомогательной функции для чтения файловой системы
Далее мы создадим вспомогательную функцию для разбора данных из файловой системы. С помощью этой функции мы хотим:
- Разбирать каждый markdown-файл и получать
title
,date
и имя файла (которое будет использоваться какid
для URL поста). - Выводить список данных на индексной странице, отсортированный по дате.
Создайте корневую директорию с названием lib
в корне проекта. Затем внутри lib
создайте файл posts.js
и скопируйте в него этот код:
import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';
const postsDirectory = path.join(process.cwd(), 'posts');
export function getSortedPostsData() {
// Получаем имена файлов из /posts
const fileNames = fs.readdirSync(postsDirectory);
const allPostsData = fileNames.map((fileName) => {
// Удаляем ".md" из имени файла, чтобы получить id
const id = fileName.replace(/\.md$/, '');
// Читаем markdown-файл как строку
const fullPath = path.join(postsDirectory, fileName);
const fileContents = fs.readFileSync(fullPath, 'utf8');
// Используем gray-matter для разбора метаданных поста
const matterResult = matter(fileContents);
// Объединяем данные с id
return {
id,
...matterResult.data,
};
});
// Сортируем посты по дате
return allPostsData.sort((a, b) => {
if (a.date < b.date) {
return 1;
} else {
return -1;
}
});
}
Примечание:
Вам не нужно понимать, что делает код выше, чтобы изучить Next.js — эта функция нужна для того, чтобы пример с блогом работал. Но если вам интересно:
fs
— это модуль Node.js, который позволяет читать файлы из файловой системы.path
— это модуль Node.js, который позволяет работать с путями к файлам.matter
— это библиотека для разбора метаданных в markdown-файлах.- В Next.js папка
lib
не имеет фиксированного названия, как папкаpages
, поэтому вы можете назвать её как угодно. Обычно используютlib
илиutils
.
Получение данных блога
Теперь, когда данные блога разобраны, нам нужно добавить их на нашу индексную страницу (pages/index.js
). Мы можем сделать это с помощью метода Next.js для получения данных под названием getStaticProps()
. В следующем разделе мы узнаем, как реализовать getStaticProps()
.
Давайте сделаем это на следующей странице!