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 4 | Next.js (React 生态) |
| UI | Nuxt UI + Tailwind CSS v4 | Vuetify, Element Plus |
| 状态 | Pinia + useState | VueUse |
| ORM | Drizzle ORM | Prisma |
| 数据库 | PostgreSQL | MySQL, SQLite |
| 认证 | nuxt-auth-utils | Lucia Auth |
| 校验 | Zod | Valibot, Yup |
| 测试 | Vitest + @nuxt/test-utils | Jest |
| E2E | Playwright | Cypress |
| 部署 | Docker + PM2 | Vercel, 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 命名规范
| 类别 | 规范 | 示例 |
|---|---|---|
| 组件 | PascalCase | VideoCard.vue |
| Composable | camelCase,use 前缀 | useVideoPlayer.ts |
| API 路由 | kebab-case,方法后缀 | [id].get.ts |
| 数据库表 | snake_case 复数 | video_comments |
| 数据库列 | snake_case | created_at |
| TypeScript 类型 | PascalCase | VideoWithAuthor |
| 常量 | UPPER_SNAKE_CASE | MAX_FILE_SIZE |
| CSS 类 | Tailwind utility | flex 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 编码效率