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

Next.js 9.2

Next.js 9.2 представляет нативную поддержку CSS, агрессивное разделение кода, универсальные динамические маршруты и многое другое!

Сегодня мы рады представить Next.js 9.2 с новыми возможностями:

Все эти улучшения являются обратно совместимыми и не требуют изменений в коде. Для обновления достаточно выполнить:

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

Встроенная поддержка CSS для глобальных стилей

Next.js 5 представил поддержку импорта CSS через пользовательский плагин next-css, который расширял функциональность Next.js.

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

Кроме того, next-css имел некоторые ограничения при импорте CSS. Например, можно было импортировать CSS-файл в каждом файле проекта, но этот импортированный файл CSS был глобальным для всего приложения.

Чтобы улучшить опыт разработчиков и решить эти проблемы, мы начали работу над встроенной поддержкой импорта CSS в Next.js.

Мы рады объявить, что Next.js теперь имеет нативную поддержку импорта таблиц стилей в ваше приложение.

Чтобы начать использовать импорт CSS в вашем приложении, импортируйте CSS-файл в pages/_app.js.

Например, рассмотрим следующую таблицу стилей styles.css в корне вашего проекта:

body {
  padding: 20px 20px 60px;
  margin: 0;
}

Создайте файл pages/_app.js, если его еще нет.

Затем импортируйте файл styles.css:

pages/_app.js
import '../styles.css';
 
// Этот экспорт по умолчанию обязателен в новом файле `pages/_app.js`.
export default function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />;
}

Поскольку таблицы стилей по своей природе глобальны, они должны быть импортированы в пользовательский компонент <App>. Это необходимо, чтобы избежать конфликтов имен классов и порядка для глобальных стилей.

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

В продакшене все CSS-файлы будут автоматически объединены в один минифицированный .css файл. Этот CSS-файл будет загружен через тег <link> и автоматически встроен в HTML-разметку, генерируемую Next.js.

Эта новая функция полностью обратно совместима. Если вы используете @zeit/next-css или другие CSS-плагины, функция будет отключена, чтобы избежать конфликтов.

Если вы в настоящее время используете @zeit/next-css, мы рекомендуем удалить плагин из вашего next.config.js и package.json, перейдя на встроенную поддержку CSS после обновления.

Встроенная поддержка CSS Modules для стилей уровня компонента

Next.js теперь поддерживает CSS Modules с использованием соглашения об именовании файлов [name].module.css.

В отличие от поддержки, ранее доступной в Next.js 5 с использованием next-css, глобальные CSS и CSS Modules теперь могут сосуществоватьnext-css требовал, чтобы все .css файлы в приложении обрабатывались либо как глобальные, либо как локальные, но не оба варианта одновременно.

CSS Modules локально ограничивают CSS, автоматически создавая уникальные имена классов. Это позволяет использовать одно и то же имя CSS-класса в разных файлах без опасения конфликтов.

Такое поведение делает CSS Modules идеальным способом включения CSS на уровне компонента. Файлы CSS Modules могут быть импортированы в любом месте вашего приложения.

Например, рассмотрим повторно используемый компонент Button в папке components/:

Сначала создайте components/Button.module.css со следующим содержимым:

/*
Вам не нужно беспокоиться о том, что .error {} конфликтует с другими `.css` или
`.module.css` файлами!
*/
.error {
  color: white;
  background-color: red;
}

Затем создайте components/Button.js, импортируя и используя вышеуказанный CSS-файл:

components/Button.js
import styles from './Button.module.css';
 
export function Button() {
  return (
    <button
      type="button"
      // Обратите внимание, как класс "error" доступен как свойство импортированного
      // объекта `styles`.
      className={styles.error}
    >
      Destroy
    </button>
  );
}

CSS Modules — это опциональная функция и работает только для файлов с расширением .module.css. Обычные таблицы стилей <link> и глобальные CSS-файлы по-прежнему поддерживаются.

В продакшене все файлы CSS Modules автоматически объединяются в множество минифицированных и разделенных .css файлов. Эти .css файлы представляют горячие пути выполнения в вашем приложении, гарантируя загрузку минимального количества CSS для отрисовки каждой страницы.

Как и выше, эта новая функция полностью обратно совместима. Если вы используете @zeit/next-css или другие CSS-плагины, функция будет отключена, чтобы избежать конфликтов.

Если вы в настоящее время используете @zeit/next-css, мы рекомендуем удалить плагин из вашего next.config.js и package.json, перейдя на встроенную поддержку CSS.

Улучшенная стратегия разделения кода

Версии Next.js до 9.2 имели фиксированный набор JavaScript-бандлов, необходимых для загрузки и интерактивности страницы:

  • JavaScript-файл страницы
  • Файл с общим JavaScript
  • Клиентский бандл Next.js
  • Клиентский бандл Webpack
  • Динамические импорты (добавляемые через next/dynamic, при использовании)

Чтобы страница стала интерактивной, все эти бандлы должны загрузиться, так как они зависят друг от друга для запуска React в браузере.

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

По этой причине Next.js использовал commons бандл, содержащий общий JavaScript между страницами. Расчет старой стратегии разделения бандлов для генерации commons основывался на эвристике соотношения использования. Если модуль использовался более чем в 50% всех страниц, он помечался как общий модуль. В противном случае он включался в JavaScript-файл страницы.

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

Наша цель — оптимизировать все типы страниц в одном приложении.

Alex Castle предложил новый метод чанкинга (создания отдельных JavaScript-файлов), который позволяет оптимизировать общие чанки с несколькими файлами, включая случаи с множеством типов страниц.

Сегодня мы рады объявить, что это новое поведение чанкинга включено по умолчанию в Next.js 9.2. Мы хотели бы выразить глубокую благодарность команде Google Chrome и Alex Castle за вклад в это изменение. Это изменение отражает совокупные усилия недель исследований, лабораторных тестов, тестирования в реальных условиях и реализации.

Новая реализация чанкинга использует HTTP/2 для доставки большего количества чанков меньшего размера.

Согласно новой эвристике, чанки создаются для:

  • Минимального чанка для каждой страницы.
  • Чанка фреймворка, содержащего React, ReactDOM, Scheduler React и т.д.
  • Чанков библиотек для любых зависимостей node_module размером более 160kb (до минификации/gzip)
  • Общего чанка для кода, используемого на всех страницах.
  • Максимально возможного количества общих чанков (используемых 2 или более страницами), оптимизируя общий размер приложения и скорость начальной загрузки.
  • Клиентского рантайма Next.js.
  • Рантайма Webpack.

Давайте посмотрим, что это значит в реальном приложении:

Ранний партнер из индустрии, Barnebys®, увидел уменьшение общего размера приложения на 23%.

Кроме того, их самый большой JS-бандл уменьшился на 30% — с 605kB до 425kB — без изменений в коде.

Другой партнер, SumUp®, увидел уменьшение своего самого большого JS-бандла на 70% — с 395kB до 122kB — без изменений в коде.

Самый большой JavaScript-бандл

ДоПослеРазница
Barnebys605kB425kB30% меньше
SumUp395kB122kB70% меньше

Новое поведение чанкинга не только уменьшает общий размер и размер начальной загрузки, но и последующие клиентские навигации. Barnebys® увидел уменьшение количества загружаемого JavaScript на 87% после шести (6) переходов между страницами:

JavaScript, загружаемый при множественных клиентских переходах

ДоПослеРазница
Barnebys136kB18kB87% меньше

Это новое поведение полностью обратно совместимо. Для использования этого улучшения производительности достаточно обновить Next.js до последней версии.

Универсальные динамические маршруты

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

Однако оставались случаи, которые эта функция не охватывала.

Одним из таких случаев были универсальные маршруты. Например, маршрутизация подстановочного знака, такого как /post/**, как страницы. Это особенно полезно, когда у вас есть вложенная структура, определяемая источником контента, таким как CMS.

Теперь вы можете создавать универсальные динамические маршруты, используя синтаксис [...name].

Например, pages/post/[...slug].js будет соответствовать /post/a, /post/a/b, /post/a/b/c и так далее.

slug будет предоставлен в объекте запроса маршрутизатора как массив отдельных частей пути. Так, для пути /post/foo/bar объект запроса будет { slug: ['foo', 'bar'] }.

Сообщество

Мы очень рады видеть постоянный рост популярности Next.js:

  • У нас было более 880 независимых участников.
  • На GitHub проект получил более 44,000 звезд.
  • Каталог примеров содержит более 220 примеров.

Сообщество Next.js теперь насчитывает более 13,800 участников. Присоединяйтесь к нам!

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