BackНазад к блогу

Next.js 12.2

Next.js 12.2 представляет стабильные Middleware и On-Demand ISR, экспериментальные Edge SSR и API Routes, а также многое другое!

Мы закладываем фундамент для будущего Next.js с версией 12.2:

Обновитесь сегодня, выполнив npm i next@latest.

Middleware (стабильная версия)

Мы рады объявить, что Middleware теперь стабилен в версии 12.2 и имеет улучшенный API на основе отзывов пользователей.

Middleware позволяет выполнять код до завершения запроса. На основе входящего запроса вы можете изменить ответ, переписав его, перенаправив, добавив заголовки или установив куки.

middleware.ts
import { NextRequest, NextResponse } from 'next/server';
 
// Если входящий запрос содержит куку "beta",
// то мы перепишем запрос на /beta
export function middleware(req: NextRequest) {
  const isInBeta = JSON.parse(req.cookies.get('beta') || 'false');
  req.nextUrl.pathname = isInBeta ? '/beta' : '/';
  return NextResponse.rewrite(req.nextUrl);
}
 
// Поддерживается как одиночное значение, так и массив совпадений
export const config = {
  matcher: '/',
};

Для обновления до последних изменений API Middleware ознакомьтесь с руководством по миграции.

Попробуйте Middleware бесплатно на Vercel или при самостоятельном хостинге с использованием next start.

On-Demand Incremental Static Regeneration (стабильная версия)

On-Demand Incremental Static Regeneration (ISR) позволяет обновлять контент на вашем сайте без необходимости передеплоя. Это упрощает немедленное обновление сайта при изменении данных в вашей headless CMS или коммерческой платформе. Это была одна из самых востребованных функций сообщества, и мы рады, что она теперь стабильна.

pages/api/revalidate.js
export default async function handler(req, res) {
  // Проверка секретного токена для подтверждения валидности запроса
  if (req.query.secret !== process.env.MY_SECRET_TOKEN) {
    return res.status(401).json({ message: 'Неверный токен' });
  }
 
  try {
    await res.revalidate('/path-to-revalidate');
    return res.json({ revalidated: true });
  } catch (err) {
    // При возникновении ошибки Next.js продолжит
    // показывать последнюю успешно сгенерированную страницу
    return res.status(500).send('Ошибка повторной валидации');
  }
}

Incremental Static Regeneration работает с любыми провайдерами, поддерживающими Next.js Build API (next build). При деплое на Vercel on-demand ревалидация распространяется глобально за ~300 мс при отправке страниц на граничную сеть.

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

Edge API Routes (экспериментальная версия)

Next.js теперь также поддерживает использование Edge Runtime для API Routes. Edge Runtime — это более легковесная среда выполнения по сравнению с Node.js, обеспечивающая быстрое стартование для низкой задержки. Кроме того, Edge API Routes поддерживают потоковую передачу ответов с сервера.

Вы можете установить среду выполнения для API Route в config, указав либо nodejs (по умолчанию), либо experimental-edge:

pages/api/hello.js
import type { NextRequest } from 'next/server';
 
export default (req: NextRequest) => {
  return new Response(`Привет, с ${req.url} я теперь Edge API Route!`);
};
 
export const config = {
  runtime: 'experimental-edge',
};

Поскольку Edge Runtime легковесен, он имеет ограничения для обеспечения быстрого старта — например, не поддерживает специфичные для Node.js API, такие как fs. Поэтому средой выполнения по умолчанию для API Routes остается nodejs.

Для получения дополнительной информации ознакомьтесь с документацией.

Edge Server-Rendering (экспериментальная версия)

Next.js теперь поддерживает использование Edge Runtime для серверного рендеринга.

Как упоминалось выше, Edge Runtime — это более легковесная среда выполнения по сравнению с Node.js, обеспечивающая быстрое стартование для низкой задержки. При использовании с React 18 он позволяет осуществлять потоковый серверный рендеринг для страниц.

Next.js использует Node.js в качестве среды выполнения по умолчанию для серверного рендеринга страниц. Начиная с версии 12.2, если вы используете React 18, вы можете выбрать использование Edge Runtime.

Вы можете установить среду выполнения глобально в next.config.js, указав либо nodejs, либо experimental-edge:

next.config.js
module.exports = {
  experimental: {
    runtime: 'experimental-edge',
  },
};

Изменение среды выполнения по умолчанию для страниц влияет на все страницы, включая функции SSR streaming и Server Components. Вы также можете переопределить это значение по умолчанию для каждой страницы, экспортировав конфигурацию runtime:

pages/index.js
export const config = {
  runtime: 'nodejs',
};
 
export default function Home() {}

Вы можете определить, какую среду выполнения вы используете, проверив переменную окружения process.env.NEXT_RUNTIME во время выполнения и изучив переменную options.nextRuntime во время компиляции webpack.

Для получения дополнительной информации ознакомьтесь с документацией.

Улучшения next/image

next/future/image компонент (экспериментальная версия)

Мы услышали ваши отзывы о текущем компоненте Image и рады поделиться ранним превью нового next/image. Этот новый и улучшенный компонент изображения требует меньше клиентского JavaScript и упрощает стилизацию изображений:

  • Рендерит один <img> без оберток <div> или <span>
  • Добавлена поддержка стандартного пропа style
  • Удалены пропсы layout, objectFit и objectPosition в пользу style или className
  • Удалена реализация IntersectionObserver в пользу нативной ленивой загрузки
  • Удалена конфигурация loader в пользу пропа loader
  • Примечание: пока нет режима fill, поэтому пропсы width и height обязательны

Это улучшает производительность, поскольку нативная loading="lazy" не требует ожидания гидратации React и клиентского JavaScript.

Для получения дополнительной информации ознакомьтесь с документацией.

Remote Patterns (экспериментальная версия)

next/image теперь поддерживает экспериментальную опцию конфигурации remotePatterns, которая позволяет указывать шаблоны для удаленных изображений при использовании встроенного API оптимизации изображений. Это позволяет более гибко сопоставлять изображения по сравнению с существующей конфигурацией images.domains, которая выполняет только точное совпадение по имени домена.

next.config.js
module.exports = {
  experimental: {
    images: {
      remotePatterns: [
        {
          // Имя хоста в свойстве `src` должно заканчиваться на `.example.com`,
          // иначе будет возвращен ответ 400 Bad Request.
          protocol: 'https',
          hostname: '**.example.com',
        },
      ],
    },
  },
};

Для получения дополнительной информации ознакомьтесь с документацией.

Отключение оптимизации изображений

API для оптимизации изображений с нулевой конфигурацией не позволяет использовать next export, так как требует сервер для оптимизации изображений по запросу. До сегодняшнего дня пользователям, использующим next export, приходилось настраивать loader для использования стороннего провайдера оптимизации изображений, но не было четкого решения, если провайдер отсутствовал. Начиная с сегодняшнего дня, пользователи next export могут отключить оптимизацию изображений для всех экземпляров next/image с помощью нового свойства конфигурации:

next.config.js
module.exports = {
  experimental: {
    images: {
      unoptimized: true,
    },
  },
};

SWC-плагины (экспериментальная функция)

Компилятор Next.js использует SWC для трансформации и минификации JavaScript-кода для продакшена. SWC был представлен в Next.js 12.0 для улучшения производительности как локальной разработки, так и сборки.

Теперь вы можете добавлять плагины (написанные на WebAssembly), чтобы настраивать поведение трансформации SWC во время компиляции:

next.config.js
module.exports = {
  experimental: {
    swcPlugins: [
      ['css-variable/swc', { displayName: true, basePath: __dirname }],
    ],
  },
};

Для получения дополнительной информации ознакомьтесь с документацией.

Улучшения поддержки React 18

  • Улучшена поддержка библиотек CSS-in-JS, таких как styled-components и emotion, с более плавным процессом обновления и без критических изменений.
  • Теперь полностью поддерживаются AMP и пост-оптимизация HTML (оптимизация CSS, шрифтов).
  • next/head теперь поддерживает React 18.
  • Анонсер маршрутов Next.js, который используется для корректного оповещения о переходах между страницами для скринридеров и других вспомогательных технологий, теперь поддерживает React 18.

Другие улучшения

  • Поддержка трансформации Emotion в компиляторе Next.js. Теперь поддерживается большинство функций @emotion/babel-plugin, и, если вы не используете importMap, его можно удалить. Подробнее см. в документации.
  • Улучшена поддержка трансформации styled-components в компиляторе Next.js за счет возможности настройки параметров по умолчанию, включая опцию cssProp. Подробнее см. в документации.
  • Улучшена поддержка модулей JavaScript ES, поэтому компоненты, такие как next/image и next/link, можно корректно импортировать с помощью import.
  • next/link больше не требует ручного добавления <a> в качестве дочернего элемента. Теперь можно включить это поведение с обратной совместимостью.
  • Добавлена экспериментальная поддержка отправки только современного JavaScript путем изменения browsersList. Для этого можно установить browsersListForSwc: true и legacyBrowsers: false в опции experimental файла next.config.js.
  • Новые оптимизации @swc/helpers предотвращают дублирование между бандлами, уменьшая их размер примерно на 2KB в минимальной конфигурации и больше в крупных приложениях.
  • Значительно уменьшен размер установки Next.js. Это достигнуто за счет перехода нашего монорепозитория на pnpm, что позволило удалить дублирующиеся пакеты при создании предварительно скомпилированных версий. Это привело к сокращению размера установки на 14MB.
  • В рамках наших усилий по улучшению самостоятельного хостинга Next.js мы стабилизируем экспериментальную конфигурацию outputStandalone: true в output: 'standalone'. Эта конфигурация значительно сокращает размер развертывания, включая только необходимые файлы/ресурсы, в том числе устраняя необходимость установки всех node_modules в пакете развертывания. Пример работы этой конфигурации можно увидеть в нашем примере with-docker.

RFC по макетам и поддержка расширенной маршрутизации

Если вы пропустили, в прошлом месяце мы анонсировали RFC по макетам — самое крупное обновление Next.js с момента его появления в 2016 году, включающее:

  • Вложенные макеты: Создание сложных приложений с вложенными маршрутами.
  • Оптимизация для серверных компонентов: Оптимизировано для навигации по поддеревьям.
  • Улучшенная загрузка данных: Загрузка данных в макетах без водопадов.
  • Использование возможностей React 18: Потоковая передача, переходы и Suspense.
  • Клиентская и серверная маршрутизация: Сервероцентричная маршрутизация с SPA-подобным поведением.
  • 100% постепенное внедрение: Без критических изменений для постепенного внедрения.
  • Расширенные соглашения маршрутизации: Скрытое хранение, мгновенные переходы и многое другое.

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

Благодарности участникам

Next.js — это результат совместной работы более 2000 разработчиков, отраслевых партнеров, таких как Google Chrome и Meta, и нашей основной команды в Vercel.

Этот релиз стал возможен благодаря вкладу: @huozhi, @ijjk, @kwonoj, @ViolanteCodes, @akrabdev, @timneutkens, @jpveilleux, @stigkj, @jgoping, @oof2win2, @Brooooooklyn, @CGamesPlay, @lfades, @molebox, @steven-tey, @SukkaW, @Kikobeats, @balazsorban44, @erikbrinkman, @therealmarzouq, @remcohaszing, @perkinsjr, @shuding, @hanneslund, @housseindjirdeh, @RobertKeyser, @styfle, @htunnicliff, @lukeshumard, @sagnik3, @pixelass, @JoshuaKGoldberg, @rishabhpoddar, @nguyenyou, @kdy1, @sidwebworks, @gnoff, @gaspar09, @feugy, @mfix-stripe, @javivelasco, @Chastrlove, @goncharov-vlad, @NaveenDA, @Firfi, @idkwhojamesis, @FLCN-16, @icyJoseph, @ElijahPepe, @elskwid, @irvile, @Munawwar, @ykolbin, @hulufei, @baruchadi, @imadatyatalah, @await-ovo, @menosprezzi, @gazs, @Exortions, @rubens-lopes, @woochul2, @stefee, @stmtk1, @jlarmstrongiv, @MaedahBatool, @jameshfisher, @fabienheureux, @TxHawks, @mattbrandlysonos, @iggyzap, @src200, @AkifumiSato, @hermanskurichin, @kamilogorek, @ben-xD, @dawsonbooth, @Josehower, @crutchcorn, @ericmatthys, @CharlesStover, @charlypoly, @apmatthews, @naingaungphyo, @alexandrutasica, @stefanprobst, @dc7290, @DilwoarH, @tommarshall, @stanhong, @leerob, @appsbytom, @sshyam-gupta, @saulloalmeida, @indicozy, @ArianHamdi, @Clariity, @sebastianbenz, @7iomka, @gr-qft, @Schniz, @dgagn, @sokra, @okbel, @tbvjaos510, @dmvjs, @PepijnSenders, @JohnPhamous, @kyliau, @eric-burel, @alabhyajindal, @jsjoeio, @vorcigernix, @clearlyTHUYDOAN, @splatterxl, @manovotny, @maxproske, @nvh95, @frankievalentine, @nuta, @bagpyp, @dfelsie, @qqpann, @atcastle, @jsimonrichard, @mass2527, @ekamkohli, @Yuddomack, @tonyspiro, @saurabhmehta1601, @banner4422, @falsepopsky, @jantimon, @henriqueholtz, @ilfa, @matteobruni, @ryscheng, @hoonoh, @ForsakenHarmony, @william-keller, @AleksaC, @Miikis, @zakiego, @radunemerenco, @AliYusuf95 и @dominiksipowicz.