Эта статья — перевод оригинальной статьи "Next.js 13"

Также я веду телеграм канал “Frontend по-флотски”, где рассказываю про интересные вещи из мира разработки интерфейсов.

Новая директория app (Beta)

Сегодня мы улучшаем возможности роутинга и лейаута в Next.js и согласовываем их с будущим React, вводя директорию app. Это продолжение RFC Layouts, ранее опубликованного для отзывов сообщества.

Директория app в настоящее время находится в стадии бета-тестирования, и мы пока не рекомендуем использовать его в продакшене. Вы можете использовать Next.js 13 с директорией pages со стабильными функциями, такими как: улучшенные компоненты next/image и next/link, и выбрать директорию app в своем собственном темпе. Директория pages будет по-прежнему поддерживаться в обозримом будущем.

Директория app включает в себя поддержку:

  • Layouts: Легко делитесь UI между роутами, сохраняя состояние и избегая дорогостоящего повторного рендеринга.

  • Server Components: Установка server-first по умолчанию для наиболее динамичных приложений.

  • Streaming: Отображение мгновенных состояний загрузки и потоковой передачи в единицах пользовательского интерфейса по мере их рендеринга.

  • Поддержка загрузки данных: асинхронные серверные компоненты и расширенный fetch API позволяет получение данных на уровне компонента

Layouts

Директория app/ упрощает компоновку сложных интерфейсов, которые сохраняют состояние при навигации, избегают дорогостоящих повторных рендерингов и включают расширенные шаблоны роутинга. Кроме того, вы можете вкладывать лейауты и размещать код приложения вместе с вашими роутами, такими как компоненты, тесты и стили.

Для создания роутов внутри app/ требуется один файл page.js:

// app/page.js
// This file maps to the index route (/)
export default function Page() {
  return <h1>Hello, Next.js!</h1>;
}

Затем вы можете определить лейауты через файловую систему. Лейауты используют общий UI для нескольких страниц. При навигации лейауты сохраняют состояние, остаются интерактивными и не перерисовываются.

// app/blog/layout.js
export default function BlogLayout({ children }) {
  return <section>{children}</section>;
}

Узнайте больше о лейаутах и страницах или разверните пример, чтобы опробовать его.

Server Components

В директории app/ представлена поддержка новой архитектуры React Server Components. Серверные и клиентские компоненты используют сервер и клиент для того, в чем они лучше всего — позволяя вам создавать быстрые интерактивные приложения с единой моделью программирования, которая обеспечивает отличный опыт для разработчика.

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

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

Узнайте больше о серверных компонентах или разверните пример, чтобы опробовать его.

Streaming

Директория app/ предоставляет возможность постепенного рендеринга и постепенной потоковой передачи визуализированных единиц пользовательского интерфейса клиенту.

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

При развертывании в Vercel приложения Next.js 13, использующие каталог app/, будут по умолчанию передавать ответы как в средах выполнения Node.js, так и в средах Edge для повышения производительности.

Узнайте больше о потоковой передаче или разверните пример, чтобы опробовать ее.

Получение данных

Недавняя Support for Promises RFC представляет новый мощный способ получения данных и обработки промисов внутри компонентов:

// app/page.js
async function getData() {
  const res = await fetch('https://api.example.com/...');
  // The return value is *not* serialized
  // You can return Date, Map, Set, etc.
  return res.json();
}

// This is an async Server Component
export default async function Page() {
  const data = await getData();

  return <main>{/* ... */}</main>;
}

Нативный fetch Web-API выборки также был расширен в React и Next.js. Он автоматически выполняет дедупликацию запросов на выборку и предоставляет один гибкий способ выборки, кэширования и повторной проверки данных на уровне компонентов. Это означает, что все преимущества создания статического сайта (SSG), рендеринга на стороне сервера (SSR) и инкрементной статической регенерации (ISR) теперь доступны через единый API:

// This request should be cached until manually invalidated.
// Similar to `getStaticProps`.
// `force-cache` is the default and can be omitted.
fetch(URL, { cache: 'force-cache' });

// This request should be refetched on every request.
// Similar to `getServerSideProps`.
fetch(URL, { cache: 'no-store' });

// This request should be cached with a lifetime of 10 seconds.
// Similar to `getStaticProps` with the `revalidate` option.
fetch(URL, { next: { revalidate: 10 } });

В директории app вы можете получать данные внутри лейаутов, страниц и компонентов, включая поддержку потоковой передачи ответов с сервера.

Мы обеспечиваем эргономичные способы обработки состояний загрузки и ошибок и потоковой передачи в UI по мере его рендеринга. В будущем релизе мы также улучшим и упростим мутацию данных.

Мы рады работать с опенсурс сообществом, мейнтейнерами пакетов и другими компаниями, которые вносят свой вклад в экосистему React, чтобы создать новую эру React и Next.js. Возможность совместного извлечения данных внутри компонентов и отправка меньшего количества JavaScript клиенту были двумя важными пожеланиями сообщества, которые мы рады включить в директорию app/.

Узнайте больше о получение данных или разверните пример, чтобы опробовать его.

Представляем Turbopack (альфа)

Next.js 13 включает Turbopack, новый преемник Webpack на основе Rust.

Webpack был загружен более 3 миллиардов раз. Хотя это было неотъемлемой частью веб разработки, мы достигли предела максимальной производительности, возможной с инструментами на основе JavaScript.

В Next.js 12 мы начали переход на собственные инструменты на базе Rust. Мы начали с миграции с Babel, что привело к ускорению транспиляции в 17 раз. Затем мы заменили Terser, что привело к ускорению минификации в 6 раз. Пора идти ва-банк.

Использование альфа-версии Turbopack с Next.js 13 приводит к:

  • Обновления в 700 раз быстрее, чем с Webpack

  • Обновления в 10 раз быстрее, чем с Vite

  • Холодный запуск в 4 раза быстрее, чем с Webpack

Turbopack включает только минимальные ресурсы, необходимые для разработки, поэтому время запуска очень быстрое. В приложении с 3000 модулей Turbopack загружается за 1,8 секунды. У Vite это занимает 11,4 секунды, а у Webpack — 16,5 секунды.

Turbopack имеет встроенную поддержку серверных компонентов, TypeScript, JSX, CSS и многого другого. Во время альфа-тестирования многие функции еще не поддерживаются. Мы хотели бы услышать ваши отзывы об использовании Turbopack для ускорения ваших локальных итераций.

Примечание. Turbopack в Next.js в настоящее время поддерживает только next dev. Просмотрите поддерживаемые функции. Мы также работаем над тем, чтобы добавить поддержку next build через Turbopack.

Попробуйте альфа-версию Turbopack сегодня в Next.js 13 с next dev --turbo.

next/image

Next.js 13 представляет новый мощный компонент Image, позволяющий легко отображать изображения без изменения лейаута и оптимизировать файлы по запросу для повышения производительности.

Во время опроса сообщества Next.js 70% респондентов сказали нам, что они использовали компонент Next.js Image в продакшене и, в свою очередь, увидели улучшение основных показателей веб-ресурсов. В Next.js 13 мы еще больше улучшили next/image.

Новый компонент изображения:

  • Отправляет меньше клиентского JavaScript

  • Легче стилизовать и настроить

  • Более доступный, обязательный атрибут alt по умолчанию

  • Соответствует веб-платформе

  • Быстрее, потому что нативная отложенная загрузка не требует гидратации.

import Image from 'next/image';
import avatar from './lee.png';

function Home() {
  // "alt" is now required for improved accessibility
  // optional: image files can be colocated inside the app/ directory
  return <Image alt="leeerob" src={avatar} placeholder="blur" />;
}

Узнайте больше о компоненте Image или разверните пример, чтобы опробовать его.

Обновление next/image до Next.js 13

Старый компонент Image был переименован в next/legacy/image. Мы предоставили утилиту, которая автоматически обновит ваши существующие next/image до next/legacy/image. Например, эта команда запустит утилиту в вашей директории ./pages при запуске из корня:

npx @next/codemod next-image-to-legacy-image ./pages

Узнайте больше об утилите или ознакомьтесь с документацией.

@next/font

Next.js 13 представляет совершенно новую систему шрифтов, которая:

  • Автоматически оптимизирует ваши шрифты, включая пользовательские шрифты.

  • Удаляет внешние сетевые запросы для повышения конфиденциальности и производительности.

  • Встроенный автоматический хостинг для любого файла шрифта

  • Автоматическое смещение нулевого макета с помощью свойства CSS size-adjust

Эта новая система шрифтов позволяет удобно использовать все шрифты Google с учетом производительности и конфиденциальности. Файлы CSS и шрифтов загружаются во время сборки и размещаются вместе с остальными вашими статическими ресурсами. Браузер не отправляет запросы в Google.

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

const inter = Inter();

<html className={inter.className}>

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

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

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

<html className={myFont.className}>

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

Узнайте больше о новом компоненте Font или разверните пример, чтобы опробовать его.

next/link

next/link больше не требует ручного добавления <a> в качестве дочернего элемента.

Это было добавлено в качестве экспериментальной опции в 12.2 и теперь используется по умолчанию. В Next.js 13 <Link> всегда отображает <a> и позволяет вам пересылать свойства базовому тегу. Например:

import Link from 'next/link'

// Next.js 12: `<a>` has to be nested otherwise it's excluded
<Link href="/about">
  <a>About</a>
</Link>

// Next.js 13: `<Link>` always renders `<a>`
<Link href="/about">
  About
</Link>

Узнайте больше об улучшенном компоненте Link или разверните пример, чтобы опробовать его.

Обновление next/link до Next.js 13

Чтобы обновить ваши ссылки до Next.js 13, мы предоставили утилиту, которая автоматически обновит вашу кодовую базу. Например, эта команда запустит утилиту в вашем каталоге ./pages при запуске из корня:

npx @next/codemod new-link ./pages

Узнайте больше об утилите или ознакомьтесь с документацией.

Генерация OG картинок

Социальные карточки, также известные как open-graph изображения, могут значительно повысить уровень вовлеченности кликов по вашему контенту, а некоторые эксперименты показывают повышение конверсии на 40%.

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

Мы создали новую библиотеку vercel/og, которая без проблем работает с Next.js для создания динамических социальных карточек.

// pages/api/og.jsx

import { ImageResponse } from '@vercel/og';

export const config = {
  runtime: 'experimental-edge',
};

export default function () {
  return new ImageResponse(
    (
      <div
        style={{
          display: 'flex',
          fontSize: 128,
          background: 'white',
          width: '100%',
          height: '100%',
        }}
      >
        Hello, World!
      </div>
    ),
  );
}

Этот подход в 5 раз быстрее, чем существующие решения, благодаря использованию функций Vercel Edge, WebAssembly и совершенно новой основной библиотеки для преобразования HTML и CSS в изображения и использования абстракции компонентов React.

Узнайте больше о созданииOG картинок или разверните пример, чтобы опробовать его.

Обновление Middleware API

В Next.js 12 мы представили Middleware API, чтобы обеспечить полную гибкость роутера Next.js. Мы услышали ваши отзывы о первоначальном дизайне API и добавили некоторые дополнения, чтобы улучшить опыт разработки и добавить новые мощные функции.

Теперь вы можете более легко установить заголовки в запросе:

// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export function middleware(request: NextRequest) {
  // Clone the request headers and set a new header `x-version`
  const requestHeaders = new Headers(request.headers);
  requestHeaders.set('x-version', '13');

  // You can also set request headers in NextResponse.rewrite
  const response = NextResponse.next({
    request: {
      // New request headers
      headers: requestHeaders,
    },
  });

  // Set a new response header `x-version`
  response.headers.set('x-version', '13');
  return response;
}

Теперь вы также можете предоставить ответ непосредственно из Middleware без rewrite или redirect.

// middleware.ts
import { NextRequest, NextResponse } from 'next/server';
import { isAuthenticated } from '@lib/auth';

// Limit the middleware to paths starting with `/api/`
export const config = {
  matcher: '/api/:function*',
};

export function middleware(request: NextRequest) {
  // Call our authentication function to check the request
  if (!isAuthenticated(request)) {
    // Respond with JSON indicating an error message
    return NextResponse.json(
      {
        success: false,
        message: 'Auth failed',
      },
      {
        status: 401,
      },
    );
  }
}

Для отправки ответов из Middleware в настоящее время требуется параметр конфигурации Experiment.allowMiddlewareResponseBody в файле next.config.js.

Критические изменения

  • Минимальная версия React была увеличена с 17.0.2 до 18.2.0.

  • Минимальная версия Node.js была увеличена с 12.22.0 до 14.6.0, поскольку срок службы версии 12.x истек (PR).

  • Свойство конфигурации swcMinify было изменено с false на true. См. Компилятор Next.js для получения дополнительной информации.

  • Импорт next/image был переименован в next/legacy/image. Импорт next/future/image был переименован в next/image. Доступна утилита для безопасного и автоматического переименования импортируемых файлов.

  • Дочерний элемент next/link больше не может быть <a>. Добавьте prop legacyBehavior, чтобы использовать старое поведение, или удалите для обновления. Доступна утилита для автоматического обновления вашего кода.

  • Роуты больше не запрашиваются заранее, когда User Agent является ботом.

  • Устаревшая опция target была удалена из next.config.js.

  • Поддерживаемые браузеры были изменены, чтобы отказаться от Internet Explorer и ориентироваться на современные браузеры. Вы по-прежнему можете использовать Browserslist для изменения целевых браузеров. Chrome 64+, Edge 79+, Firefox 67+, Opera 51+, Safari 12+

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

Сообщество

Шесть лет назад мы выпустили Next.js для широкой публики. Мы решили создать платформу React с нулевой конфигурацией, которая упростит работу для разработчика. Оглядываясь назад, невероятно видеть, как выросло сообщество и что мы смогли сделать вместе. Давайте продолжим.

Next.js — это результат совместной работы более 2400 отдельных разработчиков, отраслевых партнеров, таких как Google и Meta, и нашей основной команды. Next.js — это один из самых популярных способов для веб разработки, который загружают более 3 миллионов npm в неделю и получают 94 000 звезд на GitHub.

Особая благодарность команде Aurora в Google Chrome, которая помогла с фундаментальными исследованиями и экспериментами, которые привели к этому релизу.

Комментарии (1)


  1. lkoida
    12.11.2022 20:32
    +3

    Патчинг нативных методов... Ну такое. Кажется это уже проходили с prototype.js. Да и со сравнениями турбопака и других инструментов у них там не все чисто. Уже говорили и писали об этом и в Твиттере и подкасты веб стандартов разбирали.