React Junior
207 subscribers
37 photos
462 links
Изучение React с нуля
加入频道
Next.js. Image. Форматы изображений

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

Настроить разрешенные форматы можно в next.config.js в поле images.formats.

#nextjs #серверныйрендеринг #документация
🔥3👍2
Next.js. Оптимизация шрифтов

Next реально много делает для оптимизации тяжелых ресурсов. Про изображения мы уже поговорили, теперь поговорим о шрифтах. Next предоставляет удобные функции для работы с ними, в том числе и для google-шрифтов.

Все шрифты хостятся на вашем сервере (гугловские шрифты загружаются во время сборки и тоже помещаются на сервер).

Для работы понадобится пакет @next/font.

Локальные шрифты

Для локальных шрифтов используем функцию localFont. Работает и с одним файлом, и с несколькими, если разные начертания находятся в разных файлах:

import localFont from '@next/font/local';

const myFont1 = localFont({ src: './my-font.woff2' });

const myFont2 = localFont({
src: [
{
path: './Roboto-Regular.woff2',
weight: '400',
style: 'normal',
},
{
path: './Roboto-Italic.woff2',
weight: '400',
style: 'italic',
},
]
});


Функция localFont возвращает объект с полями className и style.

Применять такой загруженный шрифт нужно с помощью сгенерированного имени класса. Для нужного элемента в разметке устанавливаем проп className={myFont.className}. Теперь для этого элемента установлено нужное значение font-family.

Google-шрифты

Для гугл-шрифтов нужно импортировать функции из пакета @next/font/google. Потребуется указать подмножество шрифта и при необходимости настройки, например, вес и стиль:

import { Inter } from '@next/font/google';
import { Roboto } from '@next/font/google';

const inter = Inter({ subsets: ['latin'] })
const roboto = Roboto({
weight: '400',
subsets: ['latin'],
});
const roboto1 = Roboto({
weight: ['400', '700'],
style: ['normal', 'italic'],
subsets: ['latin'],
});


Используем эти шрифты точно так же, через className.

Шрифты в head

Можно использовать и более привычный вариант - указать шрифты в теге style с помощью синтаксиса jsx. Это следует делать в файле _app.tsx. Значение берем из myFont.style.fontFamily. Важно сделать блок со стилями глобальным (атрибут global, чтобы стили были помещены в head.

Демо: https://codesandbox.io/p/sandbox/wizardly-dream-5gv4mx?file=%2Fpages%2Findex.tsx&selection=%5B%7B%22endColumn%22%3A37%2C%22endLineNumber%22%3A3%2C%22startColumn%22%3A37%2C%22startLineNumber%22%3A3%7D%5D

В демке для документа установлен глобальный стиль с font-family: Inter (файл pages/_app.tsx). На главной странице (pages/index.tsx) загружен шрифт Pacifico. Он установлен для одного абзаца с помощью className.

Статья в документации: https://nextjs.org/docs/basic-features/font-optimization

#nextjs #серверныйрендеринг #документация #примерыкода
🔥3👍1
TypeScript в Next.js

Соберем в одном месте типы, которые использует Next:

Данные для серверного рендеринга - GetStaticProps, GetStaticPaths, GetServerSideProps

import { GetStaticProps, GetStaticPaths, GetServerSideProps } from 'next';
export const getStaticProps: GetStaticProps = async function (context) {
// ...
}
export const getStaticPaths: GetStaticPaths = async function () {
// ...
}
export const getServerSideProps: GetServerSideProps = async function (context) {
// ...
}


API-роуты - NextApiRequest, NextApiResponse

import type { NextApiRequest, NextApiResponse } from 'next'

export default function handler(req: NextApiRequest, res: NextApiResponse) {
res.status(200).json({ name: 'John Doe' })
}


Тип NextApiResponse может также принимать обобщенный тип данных ответа.

Компонент App - AppProps

import type { AppProps } from 'next/app'

export default function MyApp({ Component, pageProps }: AppProps) {
// ...
}


#nextjs #документация #typescript
👍3🔥1
Next.js. Динамические роуты

Про динамические роуты мы уже знаем: можно создать файл pages/post/[id].tsx и он будет соответствовать множеству страниц /post/1, post/2, post/hello и т.д.

При этом в компоненте страницы можно узнать конкретный id, воспользовавшись хуком useRouter (в поле router.query.id).

Но это только один уровень вложенности, то есть страницу /post/react/23 так не опишешь. Если требуется вложенная структура, Next и это умеет.

Создаем страницу pages/post/[...id].tsx и получаем все возможные пути с любым уровнем вложенности.

При этом router.query.id будет не строкой, а массивом.

Если к этому набору урлов требуется добавить еще и просто /post (без id), название файла должно выглядеть так: pages/post/[[...id]].tsx.

#nextjs #серверныйроутинг #документация
👍3🔥1
Next.js. Api-роуты: примеры использования

Обычно не следует вызывать из апи-роута другой апи, но есть пара случаев, когда можно:

- вы хотите спрятать урл, к которому обращаетесь (поэтому запрос с клиента происходит на ваш апи /api/secret, а уже оттуда - на нужный https://company.com/secret-url)
- вы хотите использовать какие-то переменные окружения для формирования запроса

#nextjs #серверныйрендеринг #документация
👍1🔥1
Next.js. Динамические api-роуты

Для апи работают те же самые правила, что и для страниц.
Динамическую часть можно указать в квадратных скобках - api/post/[id].ts.
Если добавить три точки, будут отслеживаться все уровни вложенности - api/post/[...ids].ts.
Если при этом поставить двойные квадратные скобки, то будет опциональный вариант (будет совпадение если нет параметров вообще - api/post).
Доступ к динамическим параметрам можно получить из request.query.

#nextjs #серверныйрендеринг #документация
👍4
Next.js. Request и Response Helpers

В апи-роутах у нас приходит два параметра - объект запроса (req) и объект ответа (res).

req - это экземпляр класса http.IncomingMessage, а res - http.ServerResponse, но и тот, и другой имеют дополнительные плюшки (хелперы).

- req.cookies - все отправленные куки.
- req.query - параметры строки запроса.
- req.body - тело запроса, обработанное в соответствии с content-type.

- res.status(code) - метод для установки HTTP-кода ответа
- res.json(body) - отправить JSON
- res.send(body) - отправить HTTP-ответ (строчку, объект или Buffer)
- res.redirect([status, ], path) - для редиректа
- res.revalidate(urlPath) - ревалидация страницы по запросу.

Кроме того, из каждого роута в папке pages/api мы можем экспортировать объект конфигурации:

export const config = {
api: {

}
}


Подробнее можно посмотреть в документации:
https://nextjs.org/docs/api-routes/request-helpers
https://nextjs.org/docs/api-routes/response-helpers

#nextjs #серверныйрендеринг #документация
🔥3👍1
Next.js. Деплой проекта на Vercel

Vercel - это удобный хостинг для проектов на Next.js.

Развернуть проект очень-очень просто, даже у меня быстро получилось.
Просто регистрируемся на Vercel.com, создаем репозиторий с проектом (GitHub, GitLab, BitBucket) и импортируем его в Vercel.

Полностью поддерживаются все фичи Next.js (со всякими инкрементальными регенерациями), проект автоматически пересобирается при пуше в репозиторий. Интерфейс вроде понятный. Можно даже свой домен выбрать.

Мой учебный проект: https://furrycat.vercel.app/

Есть еще вариант задеплоить на Netlify или Heroku (но сейчас Heroku не регистрирует пользователей из России).
Подробнее тут: https://dzen.ru/a/YmuUb-ZF519-uyRP

#nextjs #серверныйрендеринг #инструменты
👍2🔥1
Next.js. Деплой на Node-сервере

Если нужно развернуть проект на обычном хостинге с поддержкой Node (не на специальном Vercel), потребуются две команды:

- next build - для сборки проекта
- next start - для запуска Next-сервера

#nextjs
👍4
Next.js. Подготовка к продакшену

Статья в документации (англ.): https://nextjs.org/docs/going-to-production

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

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

#nextjs #серверныйрендеринг #документация #отложено #оптимизация
👍4
Next.js. Аутентификация

Статья в документации (англ.): https://nextjs.org/docs/authentication

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

Итак, есть два основных подхода:

1. Открывать страничку с состоянием загрузки (неаутентифицированную), а данные пользователя получать уже на клиенте и перерендеривать страницу после получения. Такую страничку можно статически генерировать, чтобы она открывалась очень быстро и можно было размещать еее на CDN.
2. Использовать SSR, то есть получать данные пользователя на сервере и возвращать страницу с контентом для уже известного пользователя. Используем для этого getServerSideProps. В этом случае не будет "моргания неавторизованного контента", а пользовать сразу получит то, что заслуживает (готовую страницу). Но если аутентификация занимает много времени, такой подход может принести проблемы.

Дальше посмотрим на примеры и готовые решения.

#nextjs #серверныйрендеринг #документация #аутентификация
👍3
Аутентификация в Next.js с использованием iron-session: Server Side Rendering

Меняем CSR на SSR: теперь запрос данных пользователя будет происходить на сервере при загрузке страницы.

Для этого добавляем нашей главной странице функцию getServerSideProps и уже внутри нее проверяем данные сессии, а объект user передаем на страницу в виде пропа.

Нам больше не нужно использовать хук useEffect для запроса данных, не нужен лоадер и роут /api/user.

Код страницы в репозитории: https://github.com/mohnatus/iron-session-ssr-demo/blob/master/pages/index.tsx

Демо: https://iron-session-ssr-demo.vercel.app/auth

#nextjs #примерыкода #документация #инструменты #аутентификация
👍3
Аутентификация в Next. Готовые решения

Мы мельком глянули на iron-session. Это довольно низкоуровневый инструмент для управления пользовательскими сессиями.

Документация Next.js предлагает еще несколько решений:

- next-auth - полноценная система аутентификации с кучей встроенных плюшек

а также:

- Auth0
- Clerk
- Firebase
- Magic
- Nhost
- Ory
- Supabase
- Supertokens
- Userbase

подробнее можно посмотреть по ссылочкам в документации: https://nextjs.org/docs/authentication#other-providers

#nextjs #документация #аутентификация #инструменты
👍2
Next.js. Тестирование: быстрый взгляд

Next подготовлен для работы с самыми популярными библиотеками тестирования: Cypress, Playwright, React Testing Library + Jest

Страница в документации со ссылками на примеры: https://nextjs.org/docs/testing

E2E тестирование пока не будем трогать, а вот на Unit поглядим.

Есть 3 способа начать использовать Jest + React Testing Library в приложении Next:

1) сразу создать приложение с нужными настройками и примерами:


npx create-next-app@latest --example with-jest with-jest-app


2) установить Jest в уже существующий проект:


npm install --save-dev jest jest-environment-jsdom @testing-library/react @testing-library/jest-dom


Затем создать файл jest.config.js, а сам конфиг создать с помощью специальной функции nextJest. Передаем ей нужные параметры, а она сама добавит в конфиг много полезного.

3) и наконец полностью ручная настройка, которая выглядит очень страшно, не буду пока разбираться:
https://nextjs.org/docs/testing#setting-up-jest-with-babel

В целом тема тестирования у нас впереди, так что еще вернемся сюда.

#nextjs #документация #тестирование #отложено
🔥3👍1
Next.js. Продвинутые опции.

Переходим к более "продвинутым" страничкам документации. Тут будет кратенькое описание со ссылками. Некоторые пункты пропускаю, потому что не разбираюсь, а некоторые хочу чуть подробнее рассмотреть.

Компилятор

Итак, в Next.js (с v12) используется специальный компилятор, написанный на Rust с использованием инструмента SWC. Он супербыстрый и производительный, гораздо круче babel и terser.

В статье https://nextjs.org/docs/advanced-features/compiler можно посмотреть кое-какие опции для точной настройки этого компилятора.

Бандлер

Вместо Webpack можно использовать Turbopack, который в 700 раз быстрее и тоже написан на Rust. Он доступен для Next v13, но нужно специально установить: https://nextjs.org/docs/advanced-features/turbopack

Динамический импорт

Next.js поддерживает динамический импорт модулей, даже предоставляет для этого специальную функцию dynamic из пакета next/dynamic. Она представляет собой комбинацию React.lazy и Suspense, позволяет отображать лоадер, пока загружается компонент и убирает часть кода из клиентского бандла, который грузится на страницу: https://nextjs.org/docs/advanced-features/dynamic-import.

Экспорт статического HTML

С помощью команды next export можно экспортировать ваше приложение в виде набора статических файлов, которые можно положить на любой сервер, чтобы они работали без Node.js. При этом, конечно, теряются многие возможности Next.js, например, SSR. Подробнее здесь: https://nextjs.org/docs/advanced-features/static-html-export.

Настройки импорта и алиасов

Поддерживаются параметры paths и baseUrl из файлов tsconfig.json и jsconfig.json. baseUrl указывает на корень проекта, из которого будут импортироваться пакеты. paths позволяет задать алиасы для импорта: https://nextjs.org/docs/advanced-features/module-path-aliases.

MDX

Поддерживается синтаксис MDX для удобной работы с Markdown: https://nextjs.org/docs/advanced-features/using-mdx


AMP

Поддерживаются AMP-страницы: https://nextjs.org/docs/advanced-features/amp-support/introduction

Настройка Babel

Если требуется настроить Babel специально под нужды проекта, достаточно просто создать файл .babelrc или babel.config.js. Там нужно обязательно указать пресет next/babel, который необходим для работы Next.
https://nextjs.org/docs/advanced-features/customizing-babel-config

Настройка PostCSS

Next по дефолту довольно неплохо обрабатывает ваш CSS, но если требуется большее, можно создать файл postcss.config.json (или .js).
https://nextjs.org/docs/advanced-features/customizing-postcss-config

Собственный сервер

Можно даже запускать собственный сервер вместо сервера Next, хотя звучит это довольно сомнительно, так как при этом мы теряем много полезных вещей. Подробнее: https://nextjs.org/docs/advanced-features/custom-server

Страница ошибки

Если недостаточно страниц 400 и 500, можно переопределить страницу ошибки полностью - создав файл pages/_error.js: https://nextjs.org/docs/advanced-features/custom-error-page

Codemodes

У Next есть функция "режимы кода" (codemodes), которая нужна для того, чтобы модифицировать старую кодовую базу под новые фичи. Например, в старых версиях Next внутри компонента Link нужно было указывать тег a, а в новых версиях это не требуется. Если у вас весь код написан в старом стиле, можно запустить команду


npx @next/codemod@latest new-link


и код, очевидно, будет исправлен.
Подробнее: https://nextjs.org/docs/advanced-features/codemods

Интернационализация

Есть встроенная поддержка интернационализации: https://nextjs.org/docs/advanced-features/i18n-routing

Security Headers

Можно настроить HTTP-заголовки, которые будут передаваться для каждого ответа - в секции headers файла next.config.js: https://nextjs.org/docs/advanced-features/security-headers

#nextjs #документация
🔥5👍2
Next.js. Продвинутые опции - 2

Режим предпросмотра

Представим, что у нас есть статическая страница, которая использует getStaticProps и/или getStaticPaths и рендерится во время сборки. Например, это страница отдельного поста.
Теперь представим, что у нас есть система управления контентом, в которой мы пишем новый пост. Хотелось бы иметь возможность увидеть, как этот пост в итоге будет выглядеть - то есть иметь превью.
То есть мы хотим использовать статическую страничку поста, но динамически, передав ей текущий черновик.
Next такое может, об этом вот здесь: https://nextjs.org/docs/advanced-features/preview-mode

Автоматическая статическая оптимизация (оптимизация статических страниц)

Этот раздел про то, что Next автоматически генерирует html для страниц, которые не используют getServerSideProps.
Тут важно помнить, что если это, например, динамический роут, то страница при рендеринге не получит параметры роута, а после гидратации получит и перерендерится.
Отследить, готовы ли параметры роута, можно, проверив поле router.isReady (хук useRouter).
Подробнее: https://nextjs.org/docs/advanced-features/automatic-static-optimization

Директория src

Фронтендерам привычно использовать для исходников директорию src. В Next же вместо этого мы размещаем все в корне проекта. При желании, можно использовать src, фреймворк это поддерживает. Тогда страницы должны лежать в папке src/pages.
Файлы конфигурации и директория public при этом должны оставаться в корне проекта.
https://nextjs.org/docs/advanced-features/src-directory

Непрерывная интеграция и кэширование сборок

Это о том, как настроить CI workflow, чтобы кэш сохранялся между сборками: https://nextjs.org/docs/advanced-features/ci-build-caching

Multi zones

Словом zone (зона?) обозначается отдельное развертывание (деплой) Next-приложения. Таких зон может быть несколько и они могут объединяться в одно приложение.
Не совсем пока понятно, что это и для чего.
Подробнее: https://nextjs.org/docs/advanced-features/multi-zones

Измерение производительности

Next.js самостоятельно собирает все метрики производительности приложения. Чтобы использовать их, нужно из файла pages/_app.js экспортировать функцию reportWebVitals. Она будет вызываться для каждой измеренной метрики.
Подробнее: https://nextjs.org/docs/advanced-features/measuring-performance

Трассировка выходных файлов

Вроде как позволяет создать сжатую версию приложения со всеми зависимостями в отдельной папке, которую можно развернуть без node_modules.

Подробнее: https://nextjs.org/docs/advanced-features/output-file-tracing

#nextjs #документация
👍5
Next.js. Middleware

С помощью миддлваров мы можем вклиниться в запрос еще до того, как он достигнет нужной страницы и, например, сделать редирект в другое место. Или еще что-нибудь полезное прикрутить вроде аутентификации или AB-тестирования.

Создать такой миддлвар очень просто - нужно просто сделать файлик middleware.js и положить его в корень проекта (рядом с папкой pages). Из этого файла нужно экспортировать функцию middleware.

В качестве параметра функция принимает объект запроса и может либо вернуть объект ответа (NextResponse), либо куда-нибудь перенаправить. Если ничего не вернуть, то запрос выполнится без всяких изменений, как будто и нет никакого миддлвара.

Соответственно, объект ответа можно сформировать как угодно, проставить ему любые заголовки и т. д.

В миддлваре, например, удобно проводить проверку на аутентификацию юзера - и если ее нет, то возвращать ошибку или перенаправлять на страничку логина.

Думаю, к этой теме мы еще вернемся, звучит она интересно.

Подробнее: https://nextjs.org/docs/advanced-features/middleware

#nextjs #документация
🔥3👍1
Next.js. Обработка ошибок

Статья в документации: https://nextjs.org/docs/advanced-features/error-handling

Тут ничего особо интересного:

development mode

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

Ошибки сервера

Если ошибка произошла на стороне сервера, пользователь увидит страницу 500 (или 404, если нужная страница не найдена).

Ошибка клиента

Для обработки клиентских ошибок нам предлагают использовать предохранитель ErrorBoundary. Импортируем его в _app.js и оборачиваем в него компонент страницы.

#nextjs #документация
👍4
#css #tip by reactive_dude

Полезный кейс использования React key
👍3