К списку постов

Релиз NextJS 11

Недавно состоялся релиз NextJS 11, поэтому давайте рассмотрим как положительные, так и отрицательные стороны этого релиза. Вначале скажу, что NextJS на текущий момент уже стал стандартом разработки сайтов, для которых необходим Server Side Rendering и статичная генерация страниц, опережая Gatsby.

Несмотря на зрелость фреймворка, точки роста ещё есть, что и показал это релиз. Что добавили:

  • Поддержка eslint из коробки
  • Улучшение производительности
  • Новый компонент Script
  • Улучшение компонента Image
  • Дефолтный webpack 5
  • Пару дополнительных фич

Поддержка eslint

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

Ведь когда ты разворачиваешь с нуля, тебе нужно:

  • Настроить TypeScript.
  • Настроить _app и метрики.
  • Сделать свой _document для корректного указания языка документа.
  • Удалить ненужное из стартового проекта.
  • Настроить подключение svg как компонентов.
  • И так далее...

Потому я надеюсь что eslint будет первым шагом к правильному стартовому шаблону, где тебя не нужно будет сразу все править руками.

Улучшение производительности

Это изменение несомненно полезное. Заявленные 40% прироста скорости в режиме dev, действительно ощущаются, особенно при работе с большими страницами. А если сравнить с NextJS 7 с которого я начал знакомство с ним - сейчас это реально удобный в работе фреймворк.

Новый компонент Script

Благодаря новому компоненту:

<Script
  src="https://other.domain/my.js"
  strategy="beforeInteractive"
/>

мы получим возможность управлять тем, в каком приоритете скрипты будут загружены. Это позволит вам оптимизировать время загрузки страниц, отложив на потом ненужные тяжелые скрипты. Мы можем передать один из 3х стратегий в свойство strategy:

  • beforeInteractive если скрипт вам нужно загрузить и исполнить перед тем, как страница становится интерактивной. Они будут в исходном HTML, который прилетит на клиент и исполнятся до вашего JS. Использовать надо осторожно, так как они будут увеличивать скорость загрузки.
  • afterInteractive будет выполняться как только страница станет интерактивной. Подходит для Яндекс метрики и прочих счетчиков. Это дефолтное поведение, если стратегия не указана.
  • lazyOnLoad как только Next нечего будет делать после отработки всех скриптов по стратегиям выше он будет получать и исполнять скрипты с этой стратегией. Чаты, звонилки, выстреливающие в лицо окна при уходе переходят сюда.

Так же мы теперь можем подписаться на загрузку скрипта и выполнить функцию, переданную в props onLoad.

Важно: теперь дефолтный способ загрузки скриптов defer, а не async, так что если есть у вас на сайте скрипты, которым важно оставить старое поведение, используйте Script со стратегией beforeInteractive.

Улучшение компонента Image

С одной стороны они действительно упростили работу:

  • Больше не нужно задавать размеры для локальных изображений, NextJS определит их автоматически.
  • Можно добавить для локальных изображений placeholder, который возводит показать легковесный blur исходного изображения, пока основная картинка не загрузилась.
  • Для не локальных изображений можно указать data:image в качестве placeholder.

Это сразу даёт из коробки правильную работу с картинками. С другой - не сделали внятную работу с SVG, как компонентами и сломали их типизацию.

Если посмотреть на их новые типы в next-env.d.ts:

declare module '*.svg' {
  /**
   * Use `any` to avoid conflicts with
   * `@svgr/webpack` plugin or
   * `babel-plugin-inline-react-svg` plugin.
   */
  const content: any

  export default content
}

Всё. Все ваши svg - просто any. Чтобы переопределить это поведение, вам нужно выкинуть из типов изображения svg и написать своё:

declare module "*.svg" {
    const content: React.FunctionComponent<React.SVGAttributes<SVGAElement>>;
    export default content;
}

Поэтому или вы живете с any для svg или ломаете типы внутри NextJS, что может плохо сказаться на обновлениях. Как добавить типизацию.

В tsconfig.json

"include": [
        "next-env-custom.d.ts",
        "images.d.ts",
        "**/*.ts",
        "**/*.tsx"
],

Где next-env-custom.d.ts это обрезанная версия типов next:

/// <reference types="next" />
/// <reference types="next/types/global" />

А в images.d.ts - доработанные типы с svg, описанные выше.

Дефолтный webpack 5

Тут одни плюсы, но надо мигрировать, если у вас модифицированный конфиг, например с SVG.

Webpack 4

module.exports = {
    webpack(config) {
        config.module.rules.push({
            test: /\.svg$/,
            issuer: {
                test: /\.(js|ts)x?$/,
            },
            use: ['@svgr/webpack'],
        });

        return config;
    },
};

Webpack 5

module.exports = {
    webpack(config, options) {
        config.module.rules.push({
            loader: '@svgr/webpack',
            options: {
                prettier: false,
                svgo: true,
                svgoConfig: {
                    plugins: [{ removeViewBox: false }],
                },
                titleProp: true,
            },
            test: /\.svg$/,
        });
        return config;
    },
};

Пару дополнительных фич

Тут детально останавливаться не буду, так как сам не тестировал:

  • Миграция Create React App на NextJS с помощью @next/codemod.
  • Next.js Live - совместная работа над проектом Next, если вы используете Vecel, как вашего хостера. Понятная фича для продажи хостинга от Vercel. В дальнейшем они обещают перевести его в open source.

Итог

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

Подпишись на статьи

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

Если хотите получать материалы и статьи каждую неделю подпишитесь на канал в Telegram PurpleCode.