2. Установка и структура
⚙️ Установка и структура проекта Nuxt 3
Заголовок раздела «⚙️ Установка и структура проекта Nuxt 3»Создание нового Nuxt 3 проекта — одна команда. Но понимание структуры файлов — это то, что превращает тебя из пользователя в мастера фреймворка. Давай разберём всё по косточкам.
Создание проекта 🚀
Заголовок раздела «Создание проекта 🚀»npx nuxi@latest init my-nuxt-app
# Или с конкретным шаблономnpx nuxi@latest init my-nuxt-app --template github:nuxt/starter#v3
# Интерактивный режим (выбор опций)npx nuxi@latest initПосле выполнения команды Nuxi спросит:
- Package manager — npm, yarn, pnpm или bun
- Initialize git repository — создать
.git
cd my-nuxt-appnpm installnpm run devОткрываем http://localhost:3000 — готово! 🎉
Команды Nuxi 🛠️
Заголовок раздела «Команды Nuxi 🛠️»# Dev серверnpx nuxi dev
# Сборка для productionnpx nuxi build
# Статическая генерация (SSG)npx nuxi generate
# Preview production сборкиnpx nuxi preview
# Добавить модульnpx nuxi module add @nuxtjs/tailwindcss
# Добавить компонент/страницу/composablenpx nuxi add component MyButtonnpx nuxi add page aboutnpx nuxi add composable useCounternpx nuxi add layout admin
# Обновить Nuxtnpx nuxi upgrade
# Проверить проектnpx nuxi info
# Очистить кэшnpx nuxi cleanupПолная структура проекта 📁
Заголовок раздела «Полная структура проекта 📁»my-nuxt-app/│├── 📁 .nuxt/ ← АВТО: типы, временные файлы│ ├── imports.d.ts ← Типы для авто-импортов│ ├── components.d.ts ← Типы для компонентов│ └── nuxt.d.ts ← Типы Nuxt│├── 📁 .output/ ← АВТО: production сборка│├── 📁 assets/ ← Ресурсы (обрабатывает Vite)│ ├── css/│ │ └── main.css ← Глобальные стили│ ├── fonts/│ └── images/│ └── logo.svg│├── 📁 components/ ← Vue компоненты (авто-импорт)│ ├── AppHeader.vue → <AppHeader>│ ├── AppFooter.vue → <AppFooter>│ ├── ui/│ │ ├── Button.vue → <UiButton>│ │ └── Card.vue → <UiCard>│ └── global/ ← Глобальные компоненты│ └── Icon.vue → <Icon> (доступен везде)│├── 📁 composables/ ← Vue composables (авто-импорт)│ ├── useAuth.ts → useAuth()│ ├── useCart.ts → useCart()│ └── utils/│ └── useFormat.ts → useFormat()│├── 📁 content/ ← @nuxt/content файлы│ ├── index.md│ └── blog/│ └── first-post.md│├── 📁 layouts/ ← Шаблоны страниц│ ├── default.vue ← Дефолтный layout│ ├── admin.vue ← Кастомный layout│ └── auth.vue ← Layout для авторизации│├── 📁 middleware/ ← Route middleware│ ├── auth.ts → named middleware 'auth'│ └── analytics.global.ts → глобальный middleware│├── 📁 pages/ ← Страницы (файловый роутинг)│ ├── index.vue → /│ ├── about.vue → /about│ ├── blog/│ │ ├── index.vue → /blog│ │ └── [slug].vue → /blog/:slug│ └── users/│ ├── index.vue → /users│ └── [id]/│ ├── index.vue → /users/:id│ └── edit.vue → /users/:id/edit│├── 📁 plugins/ ← Nuxt плагины│ ├── analytics.client.ts ← Только клиент│ ├── dayjs.ts ← Клиент + сервер│ └── error-handler.server.ts ← Только сервер│├── 📁 public/ ← Статические файлы (без обработки)│ ├── favicon.ico│ ├── robots.txt│ └── og-image.png│├── 📁 server/ ← Nitro сервер│ ├── api/ ← API маршруты│ │ ├── users.get.ts → GET /api/users│ │ ├── users.post.ts → POST /api/users│ │ └── users/│ │ └── [id].get.ts → GET /api/users/:id│ ├── routes/ ← Нестандартные маршруты│ │ └── sitemap.xml.ts → /sitemap.xml│ ├── middleware/ ← Серверный middleware│ │ └── logger.ts│ ├── plugins/ ← Nitro плагины│ │ └── database.ts│ └── utils/ ← Серверные утилиты│ └── db.ts│├── 📁 utils/ ← Клиентские утилиты (авто-импорт)│ ├── formatDate.ts → formatDate()│ └── validators.ts → validateEmail() и т.д.│├── 📄 app.vue ← Корневой компонент├── 📄 app.config.ts ← Runtime app конфиг├── 📄 error.vue ← Страница ошибок├── 📄 nuxt.config.ts ← Конфигурация Nuxt├── 📄 tsconfig.json ← TypeScript конфиг├── 📄 .env ← Переменные окружения├── 📄 .nuxtignore ← Файлы для игнорирования└── 📄 package.jsonapp.vue — точка входа 🎯
Заголовок раздела «app.vue — точка входа 🎯»<template> <!-- NuxtLayout и NuxtPage — ключевые компоненты --> <NuxtLayout> <NuxtPage /> </NuxtLayout></template>Или без layouts:
<template> <!-- Просто роутер без layouts --> <NuxtPage /></template>Или полностью кастомный:
<template> <div> <AppHeader /> <main> <NuxtPage /> </main> <AppFooter /> </div></template>nuxt.config.ts — центр управления 🎛️
Заголовок раздела «nuxt.config.ts — центр управления 🎛️»export default defineNuxtConfig({ // Совместимость с версией Nuxt compatibilityDate: '2024-04-03',
// DevTools (только в разработке) devtools: { enabled: true },
// SSR включён по умолчанию ssr: true,
// Мета-информация приложения app: { head: { title: 'My Nuxt App', titleTemplate: '%s | My App', htmlAttrs: { lang: 'ru' }, meta: [ { name: 'description', content: 'Описание сайта' }, { name: 'viewport', content: 'width=device-width, initial-scale=1' }, ], link: [ { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' } ] }, // Переходы между страницами pageTransition: { name: 'page', mode: 'out-in' }, layoutTransition: { name: 'layout', mode: 'out-in' }, },
// CSS файлы css: ['~/assets/css/main.css'],
// Глобальные компоненты/composables components: { dirs: [ '~/components', { path: '~/components/global', global: true } ] },
// Настройка авто-импортов imports: { dirs: ['stores', 'utils/**'], },
// Модули modules: [ '@nuxtjs/tailwindcss', '@pinia/nuxt', '@nuxt/image', '@nuxtjs/i18n', ],
// Runtime конфигурация runtimeConfig: { // Только серверная jwtSecret: process.env.JWT_SECRET, dbUrl: process.env.DATABASE_URL, // Публичная (клиент + сервер) public: { apiBase: process.env.NUXT_PUBLIC_API_BASE || '/api', siteName: 'My Nuxt App', } },
// Правила роутинга routeRules: { '/': { prerender: true }, '/blog/**': { isr: 3600 }, '/admin/**': { ssr: false, robots: false }, },
// Nitro конфигурация nitro: { // Предрендеринг prerender: { routes: ['/sitemap.xml', '/robots.txt'], }, // Storage (KV хранилище) storage: { redis: { driver: 'redis', url: process.env.REDIS_URL } } },
// Vite конфигурация vite: { plugins: [], css: { preprocessorOptions: { scss: { additionalData: '@import "~/assets/scss/variables";' } } } },
// TypeScript настройки typescript: { strict: true, typeCheck: true, },
// Экспериментальные фичи experimental: { viewTransition: true, typedPages: true, }}).env и переменные окружения 🔐
Заголовок раздела «.env и переменные окружения 🔐»DATABASE_URL=postgresql://user:pass@localhost/mydbJWT_SECRET=super-secret-key-123NUXT_PUBLIC_API_BASE=https://api.myapp.comNUXT_PUBLIC_APP_NAME=My Super AppВажные правила:
NUXT_PUBLIC_* → попадает в public runtimeConfigNUXT_* → попадает в private runtimeConfigОстальные → доступны только через process.env на сервере.nuxtignore — игнорирование файлов 🚫
Заголовок раздела «.nuxtignore — игнорирование файлов 🚫»# .nuxtignore — синтаксис как у .gitignore
# Игнорировать страницыpages/old-page.vuepages/experiments/**
# Игнорировать компонентыcomponents/deprecated/**
# Игнорировать test файлы в pages**/*.test.vue**/*.spec.vueapp.config.ts — публичный runtime конфиг 📦
Заголовок раздела «app.config.ts — публичный runtime конфиг 📦»// app.config.ts — конфиг доступный на клиенте// В отличие от runtimeConfig — не из ENV, а из кодаexport default defineAppConfig({ theme: { primaryColor: '#00dc82', name: 'Nuxt Green', }, ui: { button: { defaultVariants: { color: 'primary', size: 'md', } } }})<script setup>// Доступ вездеconst appConfig = useAppConfig()console.log(appConfig.theme.primaryColor) // '#00dc82'</script>Псевдонимы путей (Aliases) 📍
Заголовок раздела «Псевдонимы путей (Aliases) 📍»Nuxt автоматически создаёт удобные псевдонимы:
// В любом файле можно использовать:import MyUtil from '~/utils/myUtil' // ~ = корень проектаimport Component from '@/components/X' // @ = корень проектаimport type from '#imports' // # = .nuxt/
// В CSS:background: url('~/assets/images/bg.jpg');