24. Nuxt vs Next.js
⚖️ Nuxt 3 vs Next.js 15
Заголовок раздела «⚖️ Nuxt 3 vs Next.js 15»Оба фреймворка — лидеры SSR-экосистемы. Nuxt 3 построен на Vue 3, Next.js 15 — на React 19. Выбор зависит от команды, проекта и предпочтений. Давайте разберём детально.
🌐 Обзор фреймворков
Заголовок раздела «🌐 Обзор фреймворков»- Основан на: Vue 3 + Vite + Nitro
- Язык: TypeScript (нативно)
- Релиз: Ноябрь 2022
- Сопровождает: Команда Nuxt Labs + сообщество
- Философия: “Convention over Configuration”
Next.js 15
Заголовок раздела «Next.js 15»- Основан на: React 19 + Turbopack
- Язык: TypeScript/JavaScript
- Релиз: Октябрь 2024 (v15)
- Сопровождает: Vercel
- Философия: “App Router + React Server Components”
📊 Таблица сравнения
Заголовок раздела «📊 Таблица сравнения»| Характеристика | Nuxt 3 | Next.js 15 |
|---|---|---|
| Фреймворк | Vue 3 | React 19 |
| Роутинг | Файловый (pages/) | Файловый (app/) |
| SSR | ✅ Встроенный | ✅ Встроенный |
| SSG | ✅ prerender: true | ✅ generateStaticParams |
| ISR | ✅ swr, isr | ✅ revalidate |
| Server Components | 🔄 В разработке | ✅ React Server Components |
| State Management | Pinia (встроено) | Redux/Zustand (внешние) |
| Метаданные | useHead(), useSeoMeta() | generateMetadata() |
| Загрузка данных | useFetch, useAsyncData | fetch() в Server Components |
| API Routes | server/api/ | app/api/ |
| Middleware | middleware/ | middleware.ts |
| i18n | @nuxtjs/i18n (официальный) | next-intl, next-i18next |
| Изображения | @nuxt/image | next/image |
| Деплой | Любая платформа (Nitro) | Оптимально на Vercel |
| DevTools | Nuxt DevTools | React DevTools |
🛣️ Маршрутизация
Заголовок раздела «🛣️ Маршрутизация»Nuxt 3 (Vue Router)
Заголовок раздела «Nuxt 3 (Vue Router)»pages/├── index.vue # /├── about.vue # /about├── blog/│ ├── index.vue # /blog│ └── [slug].vue # /blog/:slug└── [...404].vue # 404<script setup lang="ts">const route = useRoute()const slug = route.params.slug
const { data: post } = await useFetch(`/api/posts/${slug}`)</script>Next.js 15 (App Router)
Заголовок раздела «Next.js 15 (App Router)»app/├── page.tsx # /├── about/│ └── page.tsx # /about├── blog/│ ├── page.tsx # /blog│ └── [slug]/│ └── page.tsx # /blog/:slug└── not-found.tsx # 404export default async function BlogPost({ params}: { params: { slug: string }}) { const post = await fetch(`/api/posts/${params.slug}`) .then(r => r.json())
return <article>{post.title}</article>}📡 Загрузка данных
Заголовок раздела «📡 Загрузка данных»<script setup lang="ts">// useFetch — SSR + автокешconst { data: users, pending } = await useFetch('/api/users')
// useAsyncData — кастомная логикаconst { data: posts } = await useAsyncData('posts', async () => { const posts = await $fetch('/api/posts') return posts.filter(p => p.published)})
// useLazyFetch — клиентская загрузкаconst { data: comments } = useLazyFetch('/api/comments')</script>Next.js 15
Заголовок раздела «Next.js 15»// Server Component (fetch с кешем)async function UserList() { const users = await fetch('/api/users', { next: { revalidate: 3600 } // ISR 1 час }).then(r => r.json())
return <ul>{users.map(u => <li key={u.id}>{u.name}</li>)}</ul>}
// Клиентский компонент'use client'function Comments() { const [comments, setComments] = useState([]) useEffect(() => { fetch('/api/comments').then(r => r.json()).then(setComments) }, []) return <div>{comments.map(c => <div key={c.id}>{c.text}</div>)}</div>}🗃️ Управление состоянием
Заголовок раздела «🗃️ Управление состоянием»Nuxt 3 + Pinia
Заголовок раздела «Nuxt 3 + Pinia»export const useUserStore = defineStore('user', () => { const user = ref(null) const isAuthenticated = computed(() => !!user.value)
async function login(credentials) { user.value = await $fetch('/api/auth/login', { method: 'POST', body: credentials }) }
return { user, isAuthenticated, login }})<script setup>const userStore = useUserStore()// Реактивно, SSR-совместимо из коробки</script>Next.js 15 + Zustand
Заголовок раздела «Next.js 15 + Zustand»import { create } from 'zustand'
const useUserStore = create((set) => ({ user: null, isAuthenticated: false, login: async (credentials) => { const user = await fetch('/api/auth/login', { method: 'POST', body: JSON.stringify(credentials) }).then(r => r.json()) set({ user, isAuthenticated: true }) }}))🎨 DX (Developer Experience)
Заголовок раздела «🎨 DX (Developer Experience)»Nuxt 3 преимущества
Заголовок раздела «Nuxt 3 преимущества»// Авто-импорт компонентов, composables, утилит// Не нужно писать import!const user = useAuth() // composableconst router = useRouter() // vue-router
// Авто-генерация TypeScript типов// .nuxt/types/ создаётся автоматически<!-- Компоненты используются без импорта --><template> <BaseButton>Нажми</BaseButton> <UserCard :user="user" /></template>Next.js 15 преимущества
Заголовок раздела «Next.js 15 преимущества»// React Server Components — нет JS на клиентеasync function HeavyComponent() { const data = await db.query('SELECT * FROM products') // Этот код НЕ попадает в клиентский JS return <div>{data.map(...)}</div>}
// Параллельные маршрутыapp/├── @modal/│ └── page.tsx # модальное окно└── page.tsx # основной контент🚀 Производительность
Заголовок раздела «🚀 Производительность»- Nitro — универсальный деплой на любую платформу
- Vite — мгновенный HMR в разработке
- Tree-shaking — автоматически
- Route Rules — гибкое кеширование по маршруту
routeRules: { '/': { prerender: true }, '/blog/**': { swr: 3600 }, '/api/**': { cors: true }}Next.js 15
Заголовок раздела «Next.js 15»- Turbopack — сборщик на Rust (быстрее Webpack)
- React Server Components — минимальный JS на клиент
- Partial Prerendering — смешанный SSR + Static
- Edge Runtime — нативная поддержка
export const runtime = 'edge' // Edge Functionexport const revalidate = 3600 // ISR📦 Экосистема
Заголовок раздела «📦 Экосистема»- nuxt.com/modules — 200+ официальных модулей
- Глубокая интеграция модулей
@nuxt/content,@nuxt/image,@nuxt/ui- Uno CSS, Tailwind, Nuxt UI Pro
Next.js 15
Заголовок раздела «Next.js 15»- npm — весь React-экосистем
- shadcn/ui, Radix UI
- Vercel Commerce, Vercel Analytics
- next-auth, next-mdx-remote
🤔 Когда выбирать Nuxt 3?
Заголовок раздела «🤔 Когда выбирать Nuxt 3?»✅ Команда знает Vue или переходит с Nuxt 2
✅ Нужна мощная i18n из коробки
✅ Файловая CMS с @nuxt/content
✅ Быстрый старт с минимальной настройкой
✅ Деплой не на Vercel — Nitro даёт свободу
🤔 Когда выбирать Next.js?
Заголовок раздела «🤔 Когда выбирать Next.js?»✅ Команда знает React ✅ Нужны React Server Components сегодня ✅ Деплой на Vercel с максимальной интеграцией ✅ Большая React-экосистема библиотек ✅ Корпоративный стандарт — React знают все