Nuxt4 项目模板与最佳实践总结

本书从第 1 章到第 77 章,覆盖了 Nuxt4 全栈开发的方方面面。本章作为收尾,把所有实践浓缩成一份可直接使用的项目模板和一系列 Checklist——新项目照着初始化,老项目对照检查。这是全书知识的"索引页",也是你开发时随手查阅的速查表。

1. 项目模板:目录结构

1.1 推荐的项目结构

nuxt4-starter/
├── .cursor/
│   └── rules/                    # Cursor AI 规则
│       ├── api-routes.md
│       └── vue-components.md
├── .cursorrules                   # Cursor 全局规则
├── CLAUDE.md                      # Claude Code 项目规范
├── .mcp.json                      # MCP 工具链配置
│
├── app/                           # Nuxt 应用目录(Nuxt4 默认)
│   ├── assets/
│   │   └── css/
│   │       └── main.css           # Tailwind 入口
│   ├── components/
│   │   ├── common/                # 通用组件
│   │   │   ├── AppHeader.vue
│   │   │   ├── AppFooter.vue
│   │   │   └── LoadingSpinner.vue
│   │   └── video/                 # 业务组件
│   │       ├── VideoCard.vue
│   │       ├── VideoPlayer.client.vue
│   │       └── VideoList.vue
│   ├── composables/
│   │   ├── useAuth.ts
│   │   ├── useVideo.ts
│   │   └── usePagination.ts
│   ├── layouts/
│   │   ├── default.vue
│   │   └── admin.vue
│   ├── middleware/
│   │   ├── auth.ts
│   │   └── admin.ts
│   ├── pages/
│   │   ├── index.vue
│   │   ├── login.vue
│   │   ├── video/
│   │   │   ├── index.vue
│   │   │   └── [id].vue
│   │   └── admin/
│   │       └── dashboard.vue
│   ├── plugins/
│   │   └── error-handler.ts
│   ├── app.vue
│   └── error.vue
│
├── server/
│   ├── api/
│   │   ├── auth/
│   │   │   ├── login.post.ts
│   │   │   ├── logout.post.ts
│   │   │   └── me.get.ts
│   │   └── videos/
│   │       ├── index.get.ts
│   │       ├── index.post.ts
│   │       ├── [id].get.ts
│   │       ├── [id].put.ts
│   │       └── [id].delete.ts
│   ├── middleware/
│   │   └── log.ts
│   └── utils/
│       ├── auth.ts
│       ├── db.ts
│       └── validation.ts
│
├── shared/
│   └── types/
│       ├── video.ts
│       ├── user.ts
│       └── api.ts
│
├── database/
│   ├── schema/
│   │   ├── users.ts
│   │   ├── videos.ts
│   │   └── index.ts
│   ├── migrations/
│   └── seed.ts
│
├── tests/
│   ├── unit/
│   ├── integration/
│   └── e2e/
│
├── nuxt.config.ts
├── app.config.ts
├── tailwind.config.ts
├── drizzle.config.ts
├── vitest.config.ts
├── tsconfig.json
├── package.json
└── .env.example

1.2 核心原则

  • app/ 目录包含所有前端代码(Nuxt4 默认迁移方向)
  • server/ 目录包含所有后端 API 和工具
  • shared/ 目录包含前后端共享的类型定义
  • database/ 目录包含 Drizzle ORM schema 和迁移
  • 业务组件按领域分子目录(video/admin/
  • .client.vue 后缀标记仅客户端组件

2. 技术选型 Checklist

2.1 核心技术栈

类别推荐选择替代方案
框架Nuxt 4Next.js (React 生态)
UINuxt UI + Tailwind CSS v4Vuetify, Element Plus
状态Pinia + useStateVueUse
ORMDrizzle ORMPrisma
数据库PostgreSQLMySQL, SQLite
认证nuxt-auth-utilsLucia Auth
校验ZodValibot, Yup
测试Vitest + @nuxt/test-utilsJest
E2EPlaywrightCypress
部署Docker + PM2Vercel, Cloudflare

2.2 选型决策树

项目规模:
├── 个人/小型项目(< 20 页面)
│   ├── 数据库:SQLite(零配置)
│   ├── 部署:Vercel / Cloudflare Pages
│   └── 认证:nuxt-auth-utils
│
├── 中型项目(20-100 页面)
│   ├── 数据库:PostgreSQL(Supabase / Neon)
│   ├── 部署:Docker + VPS
│   └── 认证:nuxt-auth-utils + OAuth
│
└── 大型项目(> 100 页面 / 多人团队)
    ├── 架构:pnpm Monorepo
    ├── 数据库:PostgreSQL + Redis
    ├── 部署:Kubernetes / Docker Swarm
    └── 认证:自建 session + RBAC

3. 代码规范总结

3.1 Vue 组件规范

<!-- 标准组件结构 -->
<script setup lang="ts">
// 1. 类型导入
import type { Video } from '~/shared/types/video'
 
// 2. Props & Emits
const props = defineProps<{
  video: Video
  showActions?: boolean
}>()
 
const emit = defineEmits<{
  like: [videoId: string]
  delete: [videoId: string]
}>()
 
// 3. Composables
const { user } = useAuth()
const router = useRouter()
 
// 4. 响应式状态
const isExpanded = ref(false)
 
// 5. 计算属性
const canEdit = computed(() => user.value?.id === props.video.authorId)
 
// 6. 方法
function handleLike() {
  emit('like', props.video.id)
}
 
// 7. 生命周期
onMounted(() => {
  // 客户端初始化逻辑
})
</script>
 
<template>
  <!-- 单根元素,语义化 HTML -->
  <article class="video-card">
    <!-- ... -->
  </article>
</template>

3.2 API 路由规范

// server/api/videos/index.post.ts
import { z } from 'zod'
 
const createVideoSchema = z.object({
  title: z.string().min(1).max(200),
  description: z.string().max(5000).optional(),
  categoryId: z.string(),
})
 
export default defineEventHandler(async (event) => {
  // 1. 认证
  const user = await requireAuth(event)
 
  // 2. 校验
  const body = await readValidatedBody(event, createVideoSchema.parse)
 
  // 3. 业务逻辑
  const video = await db.insert(videos).values({
    ...body,
    authorId: user.id,
  }).returning()
 
  // 4. 返回(明确的类型)
  return video[0]
})

3.3 命名规范

类别规范示例
组件PascalCaseVideoCard.vue
ComposablecamelCase,use 前缀useVideoPlayer.ts
API 路由kebab-case,方法后缀[id].get.ts
数据库表snake_case 复数video_comments
数据库列snake_casecreated_at
TypeScript 类型PascalCaseVideoWithAuthor
常量UPPER_SNAKE_CASEMAX_FILE_SIZE
CSS 类Tailwind utilityflex items-center

4. 项目结构最佳实践

4.1 数据流架构

浏览器(Vue 组件)
  ↓ useFetch / $fetch
Nitro API 路由(server/api/)
  ↓ Drizzle ORM
PostgreSQL 数据库

核心原则

  • 组件不直接访问数据库
  • 业务逻辑放在 API 路由或 composable 中,不放在组件中
  • 共享类型放在 shared/types/,前后端引用同一份
  • 数据校验在 API 层(Zod),不信任客户端输入

4.2 错误处理链

API 路由中:
  throw createError({ statusCode: 404, message: 'Not found' })
    ↓
Nuxt 自动处理:
  - API 调用返回对应 HTTP 状态码
  - useFetch 的 error ref 接收到错误
  - 全局 error.vue 处理未捕获的错误
    ↓
前端展示:
  - useFetch 的 { error } → 组件内展示错误
  - showError() → 全屏错误页
  - useToast() → Toast 通知

4.3 认证流程

用户登录
  ↓ POST /api/auth/login
服务端验证 → 设置 Session Cookie
  ↓
后续请求自动携带 Cookie
  ↓
API 路由用 requireAuth(event) 校验
  ↓
前端用 useUserSession() 获取状态

5. 开发工作流总结

5.1 日常开发流程

1. git checkout -b feat/xxx
2. 编写/修改代码(Cursor + Claude Code)
3. pnpm typecheck  → 类型检查
4. pnpm lint       → 代码规范
5. pnpm test       → 运行测试
6. git add + commit(Conventional Commits)
7. 创建 PR → AI Review + 人工审查
8. 合并到 main

5.2 新功能开发步骤

1. 数据库 schema → database/schema/xxx.ts
2. 生成 migration → pnpm db:generate
3. API 路由      → server/api/xxx/
4. Composable    → app/composables/useXxx.ts
5. 页面/组件     → app/pages/ 或 app/components/
6. 测试          → tests/
7. 类型检查      → pnpm typecheck
8. 提交          → feat: add xxx feature

5.3 部署 Checklist

## 部署前检查
 
### 代码质量
- [ ] pnpm typecheck 通过
- [ ] pnpm lint 通过
- [ ] pnpm test 通过
- [ ] pnpm build 成功
 
### 安全
- [ ] 所有 API 路由有认证检查
- [ ] POST/PUT 有 Zod 输入校验
- [ ] 无 v-html 渲染用户输入
- [ ] 敏感配置在 runtimeConfig 中(非 public)
- [ ] .env 不在 Git 中
 
### 性能
- [ ] 大列表使用分页
- [ ] 图片使用 NuxtImg / next-gen 格式
- [ ] 重组件使用 Lazy 前缀懒加载
- [ ] API 热数据使用 defineCachedEventHandler
- [ ] Lighthouse Performance > 90
 
### SSR
- [ ] 无浏览器 API 裸调用
- [ ] 动态内容使用 ClientOnly
- [ ] useFetch 在 setup 顶层调用
- [ ] 无 hydration mismatch 警告
 
### 部署
- [ ] 环境变量已配置(NUXT_xxx)
- [ ] 数据库 migration 已执行
- [ ] Node.js 版本 >= 20
- [ ] PM2 / Docker 配置就绪
- [ ] 健康检查端点可用(/api/health)
- [ ] 错误监控已配置(Sentry)

5.4 AI 工具链配置

## 项目 AI 配置 Checklist
 
- [ ] .cursorrules 已编写(技术栈 + 规范 + 反模式)
- [ ] CLAUDE.md 已编写(项目结构 + 命令 + 规范)
- [ ] .cursor/rules/ 按文件类型配置规则
- [ ] .mcp.json 配置 PostgreSQL + GitHub MCP
- [ ] .ai/prompts/ 常用 Prompt 模板已准备

6. nuxt.config.ts 模板

export default defineNuxtConfig({
  // 开发工具
  devtools: { enabled: true },
 
  // 模块
  modules: [
    '@nuxt/ui',
    '@nuxt/image',
    '@nuxt/fonts',
    '@pinia/nuxt',
    'nuxt-auth-utils',
  ],
 
  // 运行时配置
  runtimeConfig: {
    dbUrl: '',
    sessionSecret: '',
    public: {
      appName: 'AI Video Platform',
    },
  },
 
  // 实验特性
  experimental: {
    typedPages: true,
  },
 
  // TypeScript
  typescript: {
    strict: true,
  },
 
  // Nitro(服务端)
  nitro: {
    preset: 'node-server',
    compressPublicAssets: true,
  },
 
  // 应用配置
  app: {
    head: {
      htmlAttrs: { lang: 'zh-CN' },
      meta: [
        { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      ],
    },
  },
 
  // CSS
  css: ['~/assets/css/main.css'],
 
  // 兼容性日期
  compatibilityDate: '2025-01-01',
})

本章小结

本章浓缩了全书的核心实践:

  • 项目模板app/ + server/ + shared/ + database/ 四层结构,清晰分离前端、后端、共享类型、数据层
  • 技术选型:Nuxt4 + Drizzle + PostgreSQL + Nuxt UI + Zod 是当前最优全栈组合
  • 代码规范:组件结构(类型→Props→Composable→状态→方法)、API 结构(认证→校验→逻辑→返回)
  • 开发流程:schema → migration → API → composable → 页面 → 测试 → 提交
  • 部署检查:代码质量 + 安全 + 性能 + SSR + 部署五维度 Checklist
  • AI 配置:.cursorrules + CLAUDE.md + MCP 三件套,提升 AI 编码效率