1 added
1 removed
Original
2026-01-01
Modified
2026-02-26
1
<p><strong>Next.js - фреймворк на JavaScript, использующий React для построения Server Side Render-приложений (SSR) и статически-генерируемых сайтов. Наставник Хекслета<a>Глеб Андреев</a>рассказывает, кто создал Next.js, зачем его использовать и в чем его плюсы и минусы перед чистым React.</strong></p>
1
<p><strong>Next.js - фреймворк на JavaScript, использующий React для построения Server Side Render-приложений (SSR) и статически-генерируемых сайтов. Наставник Хекслета<a>Глеб Андреев</a>рассказывает, кто создал Next.js, зачем его использовать и в чем его плюсы и минусы перед чистым React.</strong></p>
2
<h2>Содержание</h2>
2
<h2>Содержание</h2>
3
<ul><li><a>История Next.js</a></li>
3
<ul><li><a>История Next.js</a></li>
4
<li><a>Как устроен Next.js</a></li>
4
<li><a>Как устроен Next.js</a></li>
5
<li><a>Разбираемся в архитектуре Next.js</a></li>
5
<li><a>Разбираемся в архитектуре Next.js</a></li>
6
<li><a>Как Next.js формирует доступные URL и оптимизирует страницы.</a></li>
6
<li><a>Как Next.js формирует доступные URL и оптимизирует страницы.</a></li>
7
<li><a>Директория API</a></li>
7
<li><a>Директория API</a></li>
8
<li><a>Немного про _app и _document</a></li>
8
<li><a>Немного про _app и _document</a></li>
9
<li><a>Дополнительно</a></li>
9
<li><a>Дополнительно</a></li>
10
<li><a>Развитие и будущее фреймворка</a></li>
10
<li><a>Развитие и будущее фреймворка</a></li>
11
</ul><h2>История Next.js</h2>
11
</ul><h2>История Next.js</h2>
12
<p>Фреймворк Next.js создан относительно недавно - в 2016 году внутри компании<a>Vercel</a>(ранее Zeit). Основная его задача - работа с Server Side Render-приложениями, написанными на React. Ее можно выполнять и<a>самим</a>с помощью ReactDOMServer и условного Express.js, но все-таки это не самый оптимальный способ, потому что разработчик в любом случае пишет много boilerplate-кода. Next.js выводит разработку SSR-приложений на следующий уровень и разбавляет ее различными оптимизациями.</p>
12
<p>Фреймворк Next.js создан относительно недавно - в 2016 году внутри компании<a>Vercel</a>(ранее Zeit). Основная его задача - работа с Server Side Render-приложениями, написанными на React. Ее можно выполнять и<a>самим</a>с помощью ReactDOMServer и условного Express.js, но все-таки это не самый оптимальный способ, потому что разработчик в любом случае пишет много boilerplate-кода. Next.js выводит разработку SSR-приложений на следующий уровень и разбавляет ее различными оптимизациями.</p>
13
<p>В целом, SSR-приложения можно писать и самому, просто Next.js - более оптимизированный под такие задачи (<a>Static Generation</a>и так далее) фреймворк.</p>
13
<p>В целом, SSR-приложения можно писать и самому, просто Next.js - более оптимизированный под такие задачи (<a>Static Generation</a>и так далее) фреймворк.</p>
14
<p>Работа Next.js следует<a>шести основным принципам</a>:</p>
14
<p>Работа Next.js следует<a>шести основным принципам</a>:</p>
15
<ol><li>Работа без настройки. Использование файловой системы в качестве API</li>
15
<ol><li>Работа без настройки. Использование файловой системы в качестве API</li>
16
<li>Только<a>JavaScript.</a>Все является функциями</li>
16
<li>Только<a>JavaScript.</a>Все является функциями</li>
17
<li>Автоматический Server Side Rendering и code-splitting</li>
17
<li>Автоматический Server Side Rendering и code-splitting</li>
18
<li>Механизм получения данных определяется разработчиком</li>
18
<li>Механизм получения данных определяется разработчиком</li>
19
<li>Предзагрузка для увеличения производительности</li>
19
<li>Предзагрузка для увеличения производительности</li>
20
<li>Простой деплой и развертывание</li>
20
<li>Простой деплой и развертывание</li>
21
</ol><p>Спустя годы проект оброс фичами, в его разработку и оптимизацию внес вклад сам Google, а технологией пользуются крупные компании вроде Uber, Netflix, GitHub и других. И даже в самой<a>документации</a>React его включили как один из тул-чейнов для разработки.</p>
21
</ol><p>Спустя годы проект оброс фичами, в его разработку и оптимизацию внес вклад сам Google, а технологией пользуются крупные компании вроде Uber, Netflix, GitHub и других. И даже в самой<a>документации</a>React его включили как один из тул-чейнов для разработки.</p>
22
<blockquote><h3>Читайте также:</h3>
22
<blockquote><h3>Читайте также:</h3>
23
<p>Виталий Брагилевский: о преподавании, новой работе в JetBrains и<a>книге про Haskell</a></p>
23
<p>Виталий Брагилевский: о преподавании, новой работе в JetBrains и<a>книге про Haskell</a></p>
24
</blockquote><h2>Как устроен Next.js</h2>
24
</blockquote><h2>Как устроен Next.js</h2>
25
<p>Next.js - фреймворк, использующий библиотеку React. Главное его отличие от "чистого" React - в способе рендера конечных веб-страниц. Если React загружает минимальный HTML и зачастую большой бандл JS (иногда разделенный между страницами на модули), то Next.js использует Server Side Rendering - формирование первоначального HTML на стороне сервера, используя тот же самый React.</p>
25
<p>Next.js - фреймворк, использующий библиотеку React. Главное его отличие от "чистого" React - в способе рендера конечных веб-страниц. Если React загружает минимальный HTML и зачастую большой бандл JS (иногда разделенный между страницами на модули), то Next.js использует Server Side Rendering - формирование первоначального HTML на стороне сервера, используя тот же самый React.</p>
26
<p>В процессе он оптимизирует бандлы так, чтобы не отправлять сразу на клиентскую сторону больше кода, чем действительно необходимо для конкретной страницы, а просто подгружать его позже.</p>
26
<p>В процессе он оптимизирует бандлы так, чтобы не отправлять сразу на клиентскую сторону больше кода, чем действительно необходимо для конкретной страницы, а просто подгружать его позже.</p>
27
<p>Давайте по шагам сравним процесс, происходящий после запроса страницы, используя Next.js и React. Как это выглядит на Next.js:</p>
27
<p>Давайте по шагам сравним процесс, происходящий после запроса страницы, используя Next.js и React. Как это выглядит на Next.js:</p>
28
<p><strong>Next.js</strong>:</p>
28
<p><strong>Next.js</strong>:</p>
29
<ol><li>Браузер делает запрос на страницу с информацией о товаре, например, /product/1.</li>
29
<ol><li>Браузер делает запрос на страницу с информацией о товаре, например, /product/1.</li>
30
-
<li>Сервер получает запрос, загружает необходимые данные о товаре с другого сервера, формирует HTML на основе полученных данных и необходимых в данный момент компонентов React.</li>
30
+
<li>Сервер получает запрос, загружает необходимые данные о товаре с другого сервера, формирует HTML на ��снове полученных данных и необходимых в данный момент компонентов React.</li>
31
<li>Браузер сразу получает HTML с нужной информацией и показывает его пользователю, но JS для интерактивности еще не загружен.</li>
31
<li>Браузер сразу получает HTML с нужной информацией и показывает его пользователю, но JS для интерактивности еще не загружен.</li>
32
<li>Подгрузка JS происходит после этого в фоновом режиме, после чего встраивается уже в имеющийся HTML-код - этот процесс называется hydration.</li>
32
<li>Подгрузка JS происходит после этого в фоновом режиме, после чего встраивается уже в имеющийся HTML-код - этот процесс называется hydration.</li>
33
</ol><p>Как этот процесс выглядит на React:</p>
33
</ol><p>Как этот процесс выглядит на React:</p>
34
<p><strong>React</strong>:</p>
34
<p><strong>React</strong>:</p>
35
<ol><li>Браузер делает запрос на страницу с информацией о товаре, например, /product/1.</li>
35
<ol><li>Браузер делает запрос на страницу с информацией о товаре, например, /product/1.</li>
36
<li>Сервер возвращает минимальный HTML-файл, в котором прописан импорт JS-файла, использующего React.</li>
36
<li>Сервер возвращает минимальный HTML-файл, в котором прописан импорт JS-файла, использующего React.</li>
37
<li>После загрузки HTML начинается загрузка JS.</li>
37
<li>После загрузки HTML начинается загрузка JS.</li>
38
<li>Только после загрузки JS-файла происходит создание необходимых DOM-элементов, загрузка данных с сервера и отображение полезного контента.</li>
38
<li>Только после загрузки JS-файла происходит создание необходимых DOM-элементов, загрузка данных с сервера и отображение полезного контента.</li>
39
</ol><p>Сравнив оба процесса, можно сразу заметить ключевые различия Next.js от React:</p>
39
</ol><p>Сравнив оба процесса, можно сразу заметить ключевые различия Next.js от React:</p>
40
<p><strong>Плюсы Next.js:</strong></p>
40
<p><strong>Плюсы Next.js:</strong></p>
41
<ul><li>При использовании Next.js браузер сразу получает готовый HTML с необходимой информацией, не дожидаясь загрузки JS.</li>
41
<ul><li>При использовании Next.js браузер сразу получает готовый HTML с необходимой информацией, не дожидаясь загрузки JS.</li>
42
<li>Next.js делает запросы к внешним API на стороне сервера.</li>
42
<li>Next.js делает запросы к внешним API на стороне сервера.</li>
43
</ul><p><strong>Минусы Next.js:</strong></p>
43
</ul><p><strong>Минусы Next.js:</strong></p>
44
<ul><li>Next.js загружает JS после HTML, до этого страница будет оставаться не интерактивной. Но даже так Next.js загрузит сначала минимально необходимый JS, а потом уже - весь остальной.</li>
44
<ul><li>Next.js загружает JS после HTML, до этого страница будет оставаться не интерактивной. Но даже так Next.js загрузит сначала минимально необходимый JS, а потом уже - весь остальной.</li>
45
<li>Необходимо больше серверных ресурсов, т.к. Next.js формирует HTML на стороне сервера перед отправкой его клиенту.</li>
45
<li>Необходимо больше серверных ресурсов, т.к. Next.js формирует HTML на стороне сервера перед отправкой его клиенту.</li>
46
</ul><h2>Разбираемся в архитектуре Next.js</h2>
46
</ul><h2>Разбираемся в архитектуре Next.js</h2>
47
<p>Создать новое приложение на Next.js можно с помощью готового тулкита:</p>
47
<p>Создать новое приложение на Next.js можно с помощью готового тулкита:</p>
48
<p>npx create-next-app my-app</p>
48
<p>npx create-next-app my-app</p>
49
<p><em>npx позволяет запускать исполняемые npm-пакеты без предварительной установки. Подробнее в<a>документации</a>.</em></p>
49
<p><em>npx позволяет запускать исполняемые npm-пакеты без предварительной установки. Подробнее в<a>документации</a>.</em></p>
50
<p>Эта команда создаст новое приложение в папке my-app и установит все необходимые зависимости:</p>
50
<p>Эта команда создаст новое приложение в папке my-app и установит все необходимые зависимости:</p>
51
<p>Next.js "из коробки" поддерживает<a>eslint</a>и<a>CSS-модули</a>(в папке styles). Статические файлы можно складывать в папку<em>public</em>, как и в обычном React. Но самая главная для нас папка -<em>pages</em>.</p>
51
<p>Next.js "из коробки" поддерживает<a>eslint</a>и<a>CSS-модули</a>(в папке styles). Статические файлы можно складывать в папку<em>public</em>, как и в обычном React. Но самая главная для нас папка -<em>pages</em>.</p>
52
<h2>Как Next.js формирует доступные URL и оптимизирует страницы.</h2>
52
<h2>Как Next.js формирует доступные URL и оптимизирует страницы.</h2>
53
<p>Каждый файл внутри этой папки (кроме папки api, файлов _app и _document) воспринимается Next.js как отдельная страница. Важно об этом помнить (почему - расскажем чуть дальше). Так Next.js автоматически конвертирует файловую структуру в URL, включая динамические параметры. Станет понятнее, если посмотреть на пример:</p>
53
<p>Каждый файл внутри этой папки (кроме папки api, файлов _app и _document) воспринимается Next.js как отдельная страница. Важно об этом помнить (почему - расскажем чуть дальше). Так Next.js автоматически конвертирует файловую структуру в URL, включая динамические параметры. Станет понятнее, если посмотреть на пример:</p>
54
<p>Теперь посмотрим на пример файла<em>users/[id]/index.js</em>:</p>
54
<p>Теперь посмотрим на пример файла<em>users/[id]/index.js</em>:</p>
55
<p>Здесь мы видим дефолтный экспорт (многое в Next.js работает через экспорты) основного компонента User, который выводит информацию о пользователе. Эту информацию он берет из props, но как она туда попадает?</p>
55
<p>Здесь мы видим дефолтный экспорт (многое в Next.js работает через экспорты) основного компонента User, который выводит информацию о пользователе. Эту информацию он берет из props, но как она туда попадает?</p>
56
<p>Тут Next.js дает нам два варианта, которые приводят к разному результату. Оба варианта работают как именованные экспорты:</p>
56
<p>Тут Next.js дает нам два варианта, которые приводят к разному результату. Оба варианта работают как именованные экспорты:</p>
57
<ol><li>getServerSideProps будет вызвана на каждый запрос во время работы приложения. Внутри можно делать вызовы к внешним сервисам и API, чтобы получить последнюю актуальную информацию. В зависимости от того, заходит человек на сайт впервые или просто перемещается между страницами, этот вызов будет сделан либо на сервере, либо на клиенте.</li>
57
<ol><li>getServerSideProps будет вызвана на каждый запрос во время работы приложения. Внутри можно делать вызовы к внешним сервисам и API, чтобы получить последнюю актуальную информацию. В зависимости от того, заходит человек на сайт впервые или просто перемещается между страницами, этот вызов будет сделан либо на сервере, либо на клиенте.</li>
58
<li>getStaticProps будет вызвана один раз при сборке приложения, она подготовит готовые HTML-файлы. Скажем, у вас есть список статей, которые обновляются редко. Их можно заранее отрендерить с помощью getStaticProps, и эти страницы будут быстрее загружаться, так как вся информация у них уже есть.</li>
58
<li>getStaticProps будет вызвана один раз при сборке приложения, она подготовит готовые HTML-файлы. Скажем, у вас есть список статей, которые обновляются редко. Их можно заранее отрендерить с помощью getStaticProps, и эти страницы будут быстрее загружаться, так как вся информация у них уже есть.</li>
59
</ol><p>Обе функции нужно экспортировать именно с таким именованным экспортом, чтобы Next.js их увидел и использовал.</p>
59
</ol><p>Обе функции нужно экспортировать именно с таким именованным экспортом, чтобы Next.js их увидел и использовал.</p>
60
<p><em>Сноска: если на странице нет динамического контента, она не подгружает данные с сервера и просто содержит статический контент, то Next.js оптимизирует ее и подготовит готовый HTML-файл, который будет просто отдаваться клиенту. Из-за этого в директории pages нельзя хранить непосредственно компоненты. Next.js будет воспринимать их как отдельные страницы и пытаться оптимизировать, что приведет к большей времени сборки. Поэтому в pages не хранят ничего, кроме простых компонентов, импортирующих контент откуда-то из другой папки.</em></p>
60
<p><em>Сноска: если на странице нет динамического контента, она не подгружает данные с сервера и просто содержит статический контент, то Next.js оптимизирует ее и подготовит готовый HTML-файл, который будет просто отдаваться клиенту. Из-за этого в директории pages нельзя хранить непосредственно компоненты. Next.js будет воспринимать их как отдельные страницы и пытаться оптимизировать, что приведет к большей времени сборки. Поэтому в pages не хранят ничего, кроме простых компонентов, импортирующих контент откуда-то из другой папки.</em></p>
61
<p>Подробнее о способах оптимизации страниц и том, как правильно их использовать, можно почитать в<a>документации</a>.</p>
61
<p>Подробнее о способах оптимизации страниц и том, как правильно их использовать, можно почитать в<a>документации</a>.</p>
62
<h2>Директория API</h2>
62
<h2>Директория API</h2>
63
<p>Это одна из новейших фичей Next.js. Она позволяет описывать методы, которые будут запускаться только на сервере. Грубо говоря, это "прослойка" между фронтендом и внешними сервисами, которую можно легко реализовать прямо в проекте.</p>
63
<p>Это одна из новейших фичей Next.js. Она позволяет описывать методы, которые будут запускаться только на сервере. Грубо говоря, это "прослойка" между фронтендом и внешними сервисами, которую можно легко реализовать прямо в проекте.</p>
64
<p>URL для доступа к API строится по тому же принципу, что и URL для страниц. Структура из примера формирует путь api/users/[id], к которому можно делать запросы с фронтенда. Давайте посмотрим на пример работы:</p>
64
<p>URL для доступа к API строится по тому же принципу, что и URL для страниц. Структура из примера формирует путь api/users/[id], к которому можно делать запросы с фронтенда. Давайте посмотрим на пример работы:</p>
65
<p>Ожидается дефолтный экспорт функции, которая будет обрабатывать запросы и возвращать ответы. Внутри нее может быть все что угодно, в нашем примере это получение пользователя по параметру id, который мы указали в URL.</p>
65
<p>Ожидается дефолтный экспорт функции, которая будет обрабатывать запросы и возвращать ответы. Внутри нее может быть все что угодно, в нашем примере это получение пользователя по параметру id, который мы указали в URL.</p>
66
<p>Так как этот метод выполняется только на сервере, мы можем безопасно обращаться к внешним сервисам и переменным окружения, не показывая лишнюю информацию на клиенте. Грубо говоря, это лишь прослойка между фронтендом и различными API, полноценный бэкенд здесь делать не стоит.</p>
66
<p>Так как этот метод выполняется только на сервере, мы можем безопасно обращаться к внешним сервисам и переменным окружения, не показывая лишнюю информацию на клиенте. Грубо говоря, это лишь прослойка между фронтендом и различными API, полноценный бэкенд здесь делать не стоит.</p>
67
<h2>Немного про _app и _document</h2>
67
<h2>Немного про _app и _document</h2>
68
<p><a>_app</a>и<a>_document</a>используются для кастомизации всех страниц одновременно, но служат разным функциям.</p>
68
<p><a>_app</a>и<a>_document</a>используются для кастомизации всех страниц одновременно, но служат разным функциям.</p>
69
<p>_app нужен для построения общей логики между всеми страницами. Например, сюда можно подключить Redux, сервисы аутентификации, различные кэши и так далее. Если вы используете getServerSideProps или getInitialProps (его старший deprecated брат) внутри _app, то все ваши страницы начинают обрабатываться в runtime - и это отключает статическую оптимизацию (и NextJS поспешит вам об этом сообщить).</p>
69
<p>_app нужен для построения общей логики между всеми страницами. Например, сюда можно подключить Redux, сервисы аутентификации, различные кэши и так далее. Если вы используете getServerSideProps или getInitialProps (его старший deprecated брат) внутри _app, то все ваши страницы начинают обрабатываться в runtime - и это отключает статическую оптимизацию (и NextJS поспешит вам об этом сообщить).</p>
70
<p>_document нужен для редактирования HTML-шаблона, который используется при рендере всех страниц. Чаще всего вам не понадобится добавлять и изменять его, но он нужен для подключения css-in-js или рендера различных статических блоков html, которые всегда будут в шаблоне страницы.</p>
70
<p>_document нужен для редактирования HTML-шаблона, который используется при рендере всех страниц. Чаще всего вам не понадобится добавлять и изменять его, но он нужен для подключения css-in-js или рендера различных статических блоков html, которые всегда будут в шаблоне страницы.</p>
71
<h2>Дополнительно</h2>
71
<h2>Дополнительно</h2>
72
<p>Next.js предоставляет функции и компоненты, которые нужны для определенных случаев. Краткое описание самых часто используемых:</p>
72
<p>Next.js предоставляет функции и компоненты, которые нужны для определенных случаев. Краткое описание самых часто используемых:</p>
73
<ul><li><p><a>next/router</a>- модуль для работы с роутером Next.js. Нужен для программных редиректов, получения данных из URL на клиенте.</p>
73
<ul><li><p><a>next/router</a>- модуль для работы с роутером Next.js. Нужен для программных редиректов, получения данных из URL на клиенте.</p>
74
</li>
74
</li>
75
<li><p><a>next/link</a>- компонент Link, который рендерит "правильные" ссылки. В HTML-разметке они будут обычными тегами<a>и сработают, даже если JS у пользователя отключен. Если JS включен, то по клику произойдет переход с помощью клиентского рендера и оптимизаций Next.js.</a></p>
75
<li><p><a>next/link</a>- компонент Link, который рендерит "правильные" ссылки. В HTML-разметке они будут обычными тегами<a>и сработают, даже если JS у пользователя отключен. Если JS включен, то по клику произойдет переход с помощью клиентского рендера и оптимизаций Next.js.</a></p>
76
<a></a></li>
76
<a></a></li>
77
<a></a><li><a></a><p><a></a><a>next/head</a>- компонент Head, который позволяет изменять контент тега <head> без оглядки на серверный/клиентский рендер.</p>
77
<a></a><li><a></a><p><a></a><a>next/head</a>- компонент Head, который позволяет изменять контент тега <head> без оглядки на серверный/клиентский рендер.</p>
78
</li>
78
</li>
79
<li><p><a>next/script</a>- компонент Script для подключения внешних скриптов на клиенте (например, метрик).</p>
79
<li><p><a>next/script</a>- компонент Script для подключения внешних скриптов на клиенте (например, метрик).</p>
80
</li>
80
</li>
81
</ul><h2>Развитие и будущее фреймворка</h2>
81
</ul><h2>Развитие и будущее фреймворка</h2>
82
<p>Вокруг Next.js сформировалось большое и активное комьюнити, а сам фреймворк активно поддерживается и развивается разработчиками. Все обновления публикуются в<a>блоге</a>и подробно описаны в<a>документации</a>, рядом с полноценным интерактивным<a>туториалом</a>). Следующие обновления будут содержать адаптацию React 18, новые файловые конвенции, параллельные запросы данных и<a>многое другое</a>.</p>
82
<p>Вокруг Next.js сформировалось большое и активное комьюнити, а сам фреймворк активно поддерживается и развивается разработчиками. Все обновления публикуются в<a>блоге</a>и подробно описаны в<a>документации</a>, рядом с полноценным интерактивным<a>туториалом</a>). Следующие обновления будут содержать адаптацию React 18, новые файловые конвенции, параллельные запросы данных и<a>многое другое</a>.</p>
83
<p>Next.js активно используют и поддерживают крупные компании вроде Google, а Vercel предлагает удобную инфраструктуру для деплоя приложений. Так что можно с уверенностью сказать, что Next.js не погибнет в ближайшем будущем, и можно спокойно использовать его для продакшена, как это и делает множество других<a>компаний</a>.</p>
83
<p>Next.js активно используют и поддерживают крупные компании вроде Google, а Vercel предлагает удобную инфраструктуру для деплоя приложений. Так что можно с уверенностью сказать, что Next.js не погибнет в ближайшем будущем, и можно спокойно использовать его для продакшена, как это и делает множество других<a>компаний</a>.</p>