javascript

Он вам не SSR. Nuxt — больше, чем Server-Side Render фреймворк

  • пятница, 7 марта 2025 г. в 00:00:06
https://habr.com/ru/articles/888356/

Привет, Хабр! Я - Frontend Developer в МТС Диджитал. Все чаще и чаще я натыкаюсь на сообщения и комментарии пользователей в различных социальных сетях про Server-Side Rendering.

Обычно эти жалобы о том, кто-то недоволен зависимостью Next.js от Node.js-сервера. Кто-то сталкивается с ограничениями динамического роутинга при статической генерации. Исходя из этого некоторые люди писали в комментариях что-то вроде: "Вы же не ожидали, что SSR-фреймворк решит все проблемы разом?"

Большинство моих коллег с других компаний в принципе не понимают зачем я беру Nuxt почти во все свои проекты и задают вопросы. На первый взгляд это вполне логично. Какой смысл брать SSR фреймворк, если ты выключаешь в нем SSR. На примере Nuxt, SSR можно выключить одним булевым флагом в конфиге:

// nuxt.config.ts
export default defineNuxtConfig({
  ssr: false
})

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

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

Nuxt Modules

И первое с чего хочется начать это Nuxt Modules. Что это за зверь такой ? Если вкратце это модульная система, которая позволяет легко добавлять функциональность в проекты без необходимости писать всё с нуля. Она помогает сэкономить приличное кол-во времени вначале вашего пути. Далее я приведу в пример несколько модулей, которые иногда использую сам.

Nuxt image

Хотите одной строчкой подключить удобный механизм работы с изображениями ? Пожалуйста вот вам Nuxt Image. Оптимизация и удобная работа с вашими картинками

<NuxtImg src="/nuxt-icon.png" />
Prewiew image with plug-and-play image optimization for Nuxt apps. Resize and transform your images using built-in optimizer or your favorite images CDN.
Prewiew image with plug-and-play image optimization for Nuxt apps. Resize and transform your images using built-in optimizer or your favorite images CDN.

Nuxt Icons

А как насчет уже готовой и удобно интегрированной работы с иконами ? Нет проблем! Вот тебе Nuxt Icons. Более 200,000+ готовых к использованию SVG иконок, почему бы и нет особенно для стартапов.

<Icon name="uil:github" style="color: black" />
Prewiew image with Icon module for Nuxt with 200,000+ ready to use icons from Iconify.
Prewiew image with Icon module for Nuxt with 200,000+ ready to use icons from Iconify.

i18n

Хочешь чтобы твое приложение использовалось по всему миру ? No problem! Для тебя уже есть готовое решение от i18n

// // nuxt.config.ts
{
  modules: [
    '@nuxtjs/i18n',
  ],
  i18n: {
    locales: [
      { code: 'en', language: 'en-US' },
      { code: 'fr', language: 'fr-FR' }
    ],
    defaultLocale: '',
  }
}
Prewiew image with i18n features for your Nuxt project so you can easily add internationalization.
Prewiew image with i18n features for your Nuxt project so you can easily add internationalization.

Nuxt Color-mode

А что насчет любимой всеми программистами тёмной темы ? Держи пожалуйста, вот тебе Nuxt сolor-mode с уже настроенным автоматическим определением темы, в зависимости от темы пользователя на устройстве (Dark/Light)

Image with Nuxt ColorMode (Dark and Light mode for Nuxt with auto detection)
Image with Nuxt ColorMode (Dark and Light mode for Nuxt with auto detection)

И это всё лишь верхушка айсберга модулей! Ну разве это не круто !?

Безусловно все эти модули можно собрать самому. Но здесь они уже готовы и настроены прямо из коробки для тебя и Nuxt. Ты можешь включать и выключать их одной кнопкой в богоподобных NuxtDevTools! Кстати это еще один "+" в копилку к сотням уже существующих модулей

Prewiew image with NuxtDevTools settings for a modules
Prewiew image with NuxtDevTools settings for a modules

Nuxt UI

Да, модули действительно отличная штука. А что если нужно быстро стартануть проект и у тебя нет ресурсов на разработку своего UI Kit-а? Кнопки, инпуты и модалки все таки нужны, а настраивать и подгонять под Quasar или упасти боже Vuetify не получается.

Тогда для тебя есть альтернатива от Nuxt. Отличный базовый набор готовых и настраиваемых компонентов.

Если честно, я не любитель готовых UI Kit-ов. Все же на длительной дистанции мне всегда не хватало их гибкости. Но буквально на днях, мне нужно было оперативно запустить небольшой интернет-магазин и здесь Nuxt UI показал себя на полную.

Prewiew image with Nuxt UI
Prewiew image with Nuxt UI

Nuxt Kit (не путать с Nuxt UI)

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

Для этого случая у нас есть Nuxt Kit он нужен для создания и управления модулями. Он упрощает процесс разработки Nuxt Modules, предоставляя удобные API для работы с настройками, хуками, файловой системой и другими возможностями фреймворка.

И да, хочу напомнить что мы все еще говорим про "SSR" фреймворк! Это значит что по мимо той малой части которую я перечислил выше, мы еще получаем все плюсы от самого SSR.

Звучит слишком хорошо, но должны же быть какие-то минусы ?

Минусы

Я считаю что плохо понимаю технологию, если не знаю или не вижу её недостатков. Исходя из этого, Nuxt на первом этапе мне казался идеальным инструментом. Если у тебя сложилось такое же впечатление, я бы хотел снять розовые очки и обсудить проблемы и нюансы.

Повышение требований для новых разработчиков.

Начну пожалуй с очевидного это повышение требований для новых разработчиков. Чтобы хорошо писать SSR, было бы неплохо понимать Node.js. Особенно, если мы говорим про написание своих модулей. Также стоит знать и помнить про "плохой код", который может вызвать утечки памяти.

Мем про современую Frontend разработку
Мем про современую Frontend разработку

Риск утечки памяти.

Несмотря на большое кол-во плюсов, в Nuxt следует быть осторожным. Есть большое кол-во подводных камней об которые вы можете споткнуться.

Изображение с мемом про утечку памяти
Изображение с мемом про утечку памяти

⌛️ setInterval / setTimeout

Чаще всего мы можем вызвать утечки когда используем setInterval на SSR. Именно он является спонсором занимательных посиделок за компьютером в субботу или воскресенье. Что же касается setTimeout, то утечки с ним происходят крайне редко.

// Пример
export default defineEventHandler(() => {
  setInterval(() => {
    console.log("Интервал работает!");
  }, 1000); // Этот интервал никогда не очищается !!!
});

Советы и рекомендации:

  • Используйте setTimeout, если код должен выполняться однократно;

  • при необходимости интервалов — очищайте их с clearInterval();

  • таймеры лучше запускать на клиенте, а не на сервере.

🚀 Ref / Computed / Watch

Также утечку памяти зачастую вызывает создание или вызов Ref / Computed / Watch ВНЕ setup.

// Пример с computed

const globalRef = ref(10);
const globalComputed = computed(() => globalRef.value * 2); // Глобальный computed

export default defineComponent({
  setup() {
    console.log(globalComputed.value); // Будет существовать в памяти навсегда!
    return { globalComputed };
  }
});

Как это можно исправить ?

// Определяем computed внутри setup()

export default defineComponent({
  setup() {
    const localRef = ref(10);
    const localComputed = computed(() => localRef.value * 2); // Авто-очищение

    return { localComputed };
  }
});

Советы и рекомендации:

  • Не создавай ref, computed и watch вне setup(), иначе они останутся в памяти навсегда;

  • определяй их внутри setup(), чтобы они автоматически очищались при уничтожении компонента;

Про утечки памяти соберу отдельную большую статью с примерами. В этом же материале даю базовый джентельменский набор 🤵‍♂️

Версионирование и сложности при миграции.

Какой Frontend разработчик не сталкивался с болью при миграции/обновлении JS библиотек. Даже если версия одной либы обновится, мы вполне можем сломать какую-то часть приложения. А что если мы переезжаем с Vue 2 на Vue 3 и у нас есть зависимости от десятков различных библиотек + большинство из которых не поддерживают Vue 3...

С Nuxt ситуация обстоит лучше. Миграция с Nuxt 2 на Nuxt 3 была непростой, но за счет Nuxt Bridge, который является неким промежуточным шагом перед миграцией это давалось легче.

Тем не менее проблема не исчезает, в Nuxt 3 произошло: изменение API, поменялась структура проекта, удалены некоторые устаревшие хуки и это лишь малая того, что вам нужно учесть при переезде. Миграцию на Nuxt 4 нам обещают легче чем на 3 версию, но как будет на самом деле увидим в будущем.

Еще немного про минусы.

Еще в этом праздник жизни нужно учесть: правильную работу с контекстом и asyncData, дебаг ошибок и утечек памяти, правильное понимание работы хуков. И это я еще не упомянул здесь про сам SSR!

Вывод

Многие воспринимают Nuxt исключительно как SSR-фреймворк. Но в реальности Nuxt — это не просто серверный рендеринг, а мощная экосистема с гибкой модульной системой.

Очень надеюсь, что в будущем Nuxt получит ещё больше внимания как универсальный мета-фреймворк для Vue 🤞🏻