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

Next.js 5.1: Ускоренное разрешение страниц, конфигурация окружения и другие улучшения

В Next.js 5.1 добавлена поддержка конфигурации окружения, фаз работы, source maps и новых плагинов Next.js.

Мы рады представить Next.js 5.1 с поддержкой конфигурации окружения, фаз работы, source maps и новых плагинов Next.js.

Основные улучшения производительности: разрешение страниц стало в 102 раза быстрее, а страницы ошибок загружаются более эффективно.

Для установки или обновления выполните:

Terminal
npm i next@latest react@latest react-dom@latest

Вместе с Next.js мы также обновили peer-зависимости react и react-dom

Не забудьте обновить плагины next-plugins, такие как @zeit/next-css, @zeit/next-sass, @zeit/next-less или @zeit/next-typescript.

Ускоренное разрешение страниц

Благодаря архитектурным изменениям в Next.js 5.0 мы смогли упростить логику разрешения страниц на основе URL-пути. Эти изменения основаны на исследовании от @oliviertassinari. Ранее разрешение страницы занимало в среднем 2.347 мс. С новой логикой разрешение той же страницы занимает в среднем 0.023 мс. Это ускорение в 102 раза для одного из наиболее часто вызываемых методов в приложениях Next.js.

Разрешение страниц по запросу. Слева Next.js 5.0, справа Next.js 5.1

Разрешение страниц по запросу. Слева Next.js 5.0, справа Next.js 5.1

Конфигурация окружения

Типичные окружения Node.js часто зависят от передачи переменных окружения в приложение, например: API_URL=https://api.vercel.com node index.js, после чего вы можете использовать API_URL в любом месте приложения через process.env.API_URL.

При универсальном рендеринге process.env недоступен на стороне клиента. Поэтому в Next 5.1 мы представляем новую функцию: publicRuntimeConfig и serverRuntimeConfig. Их можно задать в next.config.js, а затем использовать через модуль next/config.

next.config.js
module.exports = {
  serverRuntimeConfig: {
    // Доступно только на сервере
    mySecret: 'secret',
  },
  publicRuntimeConfig: {
    // Доступно и на сервере, и на клиенте
    staticFolder: '/static',
  },
};

Оба параметра serverRuntimeConfig и publicRuntimeConfig определяются в next.config.js

pages/index.js
import getConfig from 'next/config';
const { serverRuntimeConfig, publicRuntimeConfig } = getConfig();
 
console.log(serverRuntimeConfig.mySecret); // Доступно только на сервере
console.log(publicRuntimeConfig.staticFolder); // Доступно и на сервере, и на клиенте
 
export default function Index() {
  return (
    <div>
      <img src={`${publicRuntimeConfig.staticFolder}/logo.png`} />
    </div>
  );
}

Метод getConfig из модуля next/config используется для получения значений конфигурации

Улучшенная обработка ошибок

Ранее в Next.js был специальный механизм обработки ошибок для обнаружения серверных ошибок при загрузке бандлов страниц. Бандл страницы — это JavaScript-файл, загружаемый на стороне клиента для отображения страницы, например /_next/-/page/index.js.

При возникновении ошибки, такой как несоответствие ID сборки, бандл страницы всё равно возвращался с HTTP-статусом 200, но содержимым было JSON-представление ошибки, сгенерированной сервером Next.js. Это было необходимо, потому что обработка ошибок на стороне клиента зависела не только от статуса 404. Это решение работало хорошо, пока вы не попытались загрузить ассеты на статический хостинг или CDN без поддержки fallback.

В Next.js 5.1 мы полностью переработали логику обработки ошибок. Теперь, если бандл страницы возвращает HTTP-статус 404, роутер автоматически обнаруживает это и перезагружает страницу, обеспечивая навигацию между мультизонами.

При переработке этой логики мы удалили хук Router.onAppUpdated, который в основном использовался для перезагрузки страницы. Теперь страница перезагружается автоматически.

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

Фазы / функция конфигурации

Некоторые плагины next-plugins, такие как @zeit/next-css, требуются только в режиме разработки Next.js или при выполнении next build.

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

module.exports = (phase, { defaultConfig }) => config;

next.config.js экспортирует функцию, возвращающую пользовательскую конфигурацию

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

Мы представили новый модуль next/constants, содержащий часто используемые константы, включая фазы.

const {PHASE_DEVELOPMENT_SERVER} = require('next/constants')
module.exports = (phase, {defaultConfig}){
  if(phase === PHASE_DEVELOPMENT_SERVER) {
    return { /* параметры конфигурации только для разработки */ }
  }
 
  return { /* параметры конфигурации для всех фаз, кроме разработки */ }
}

next.config.js, проверяющий фазу разработки

Улучшенная генерация source maps для продакшена

С введением универсального webpack в Next.js 5 добавление source maps в продакшен-окружение стало таким же простым, как добавление нескольких строк в next.config.js:

next.config.js
module.exports = {
  webpack(config, { dev }) {
    if (!dev) {
      config.devtool = 'source-map';
      for (const plugin of config.plugins) {
        if (plugin['constructor']['name'] === 'UglifyJsPlugin') {
          plugin.options.sourceMap = true;
          break;
        }
      }
    }
    return config;
  },
};

Ручное включение source maps в next.config.js

Плагин @zeit/next-source-maps можно добавить в проект для автоматического включения source maps в продакшене. Добавьте следующее в next.config.js:

const withSourceMaps = require('@zeit/next-source-maps');
module.exports = withSourceMaps();

Использование @zeit/next-source-maps для включения source maps в next.config.js

Это позволяло генерировать source maps для всех файлов, кроме одного — app.js. Причина в том, что app.js состоял из нескольких файлов (manifest.js и commons.js), объединённых плагином webpack. Побочным эффектом было то, что webpack не мог генерировать source maps для объединённого файла.

Благодаря pull request от [@ptomasroos] файл app.js был заменён на main.js. Этот файл содержит код, который ранее компилировался в manifest.js и commons.js, и webpack теперь генерирует source map для main.js. Source maps автоматически обслуживаются, позволяя инструментам отслеживания ошибок показывать реальный файл и номер строки при обнаружении ошибок.

Исходный код отображается в панели Sources

Исходный код отображается в панели Sources

Новые плагины / улучшения существующих

Мы представили два новых официальных плагина. @zeit/next-bundle-analyzer позволяет легко настроить webpack-bundle-analyzer для анализа серверных и клиентских бандлов отдельно.

Кроме того, было внесено множество улучшений в официальные плагины css, less и sass в отношении горячей перезагрузки и сборки. Например, больше нет "мигания" нестилизованного контента в режиме разработки. Также теперь подхватываются стили в подкомпонентах.

Сообщество

Теперь сообщество Next.js можно найти на GitHub. Недавно там был опубликован список известных компаний, использующих Next.js. Вы можете добавлять свои проекты в эту ветку.

Благодарности

Мы благодарим всех, кто внёс вклад в Next.js для этого релиза. Будь то работа над ядром или расширение и улучшение нашей постоянно растущей директории примеров.

Если вы хотите начать вносить вклад в Next.js, вы можете найти задачи с метками good first issue или help wanted.

Особая благодарность Trulia за ценные отзывы, связанные с конфигурацией окружения и новой обработкой страниц ошибок.