Next.js全栈开发技能Skill nextjs

这是一个用于构建现代化全栈Web应用的专家级技能。它专注于Next.js框架,特别是App Router、React Server Components (RSC)、Server Actions、流式渲染、缓存策略和Vercel部署。该技能能帮助开发者快速搭建项目结构,实现服务器端渲染、数据获取、表单处理、API路由、高级路由模式(如并行路由、拦截路由)以及性能优化。适用于需要构建高性能、SEO友好、可扩展的Web应用程序的场景。关键词:Next.js, React, 全栈开发, App Router, Server Components, Server Actions, Vercel部署, 前端框架, Web应用开发。

前端开发 0 次安装 6 次浏览 更新于 2/26/2026

name: nextjs description: Next.js 特定模式,包括 App Router、React Server Components、Server Actions、流式渲染、缓存和 Vercel 部署。 allowed-tools: Read, Write, Edit, Bash, Glob, Grep

Next.js 技能

为使用 App Router、React Server Components、Server Actions 和现代部署模式构建全栈 Next.js 应用程序提供专家级协助。

能力

  • 使用 App Router 生成 Next.js 项目结构
  • 实现 React Server Components (RSC) 模式
  • 为表单处理和变更创建 Server Actions
  • 配置高级路由(并行路由、拦截路由、路由组)
  • 使用 Suspense 边界设置流式渲染
  • 通过重新验证实现缓存策略
  • 配置 Vercel 部署和边缘函数

使用场景

在以下情况时调用此技能:

  • 引导一个新的 Next.js 15+ 应用程序
  • 实现服务器端渲染和数据获取
  • 创建 API 路由和 Server Actions
  • 配置高级路由模式
  • 为核心 Web 指标进行优化

输入参数

参数 类型 是否必需 描述
projectName 字符串 Next.js 项目名称
router 字符串 app (默认) 或 pages
features 数组 要搭建的功能列表
database 字符串 prisma, drizzle, none
auth 字符串 nextauth, clerk, none
styling 字符串 tailwind, css-modules, styled-components

功能配置示例

{
  "projectName": "my-saas",
  "features": [
    "authentication",
    "api-routes",
    "server-actions",
    "parallel-routes",
    "middleware"
  ],
  "database": "prisma",
  "auth": "nextauth",
  "styling": "tailwind"
}

输出结构

my-saas/
├── app/
│   ├── layout.tsx                   # 根布局
│   ├── page.tsx                     # 首页
│   ├── loading.tsx                  # 加载 UI
│   ├── error.tsx                    # 错误边界
│   ├── not-found.tsx               # 404 页面
│   ├── globals.css                  # 全局样式
│   ├── (auth)/                      # 路由组
│   │   ├── login/
│   │   │   └── page.tsx
│   │   └── register/
│   │       └── page.tsx
│   ├── dashboard/
│   │   ├── layout.tsx              # 仪表板布局
│   │   ├── page.tsx
│   │   ├── @sidebar/               # 并行路由
│   │   │   └── default.tsx
│   │   └── settings/
│   │       └── page.tsx
│   └── api/
│       └── [...route]/
│           └── route.ts            # API 路由
├── components/
│   ├── ui/                         # 可复用的 UI 组件
│   └── features/                   # 特定功能组件
├── lib/
│   ├── actions/                    # Server Actions
│   │   └── user-actions.ts
│   ├── db/                         # 数据库工具
│   │   └── prisma.ts
│   └── utils/                      # 工具函数
├── middleware.ts                   # 边缘中间件
├── next.config.ts                  # Next.js 配置
├── tailwind.config.ts              # Tailwind 配置
└── package.json

生成的代码模式

App Router 布局

// app/layout.tsx
import type { Metadata } from 'next';
import { Inter } from 'next/font/google';
import './globals.css';

const inter = Inter({ subsets: ['latin'] });

export const metadata: Metadata = {
  title: {
    default: 'My SaaS',
    template: '%s | My SaaS',
  },
  description: '一个现代化的 SaaS 应用程序',
};

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body className={inter.className}>
        {children}
      </body>
    </html>
  );
}

React Server Component

// app/dashboard/page.tsx
import { Suspense } from 'react';
import { getUser } from '@/lib/db/user';
import { DashboardStats } from '@/components/features/dashboard-stats';
import { DashboardSkeleton } from '@/components/ui/skeletons';

export default async function DashboardPage() {
  const user = await getUser();

  return (
    <main className="container mx-auto py-8">
      <h1 className="text-3xl font-bold">欢迎,{user.name}</h1>

      <Suspense fallback={<DashboardSkeleton />}>
        <DashboardStats userId={user.id} />
      </Suspense>
    </main>
  );
}

Server Action

// lib/actions/user-actions.ts
'use server';

import { revalidatePath } from 'next/cache';
import { redirect } from 'next/navigation';
import { z } from 'zod';
import { prisma } from '@/lib/db/prisma';

const updateProfileSchema = z.object({
  name: z.string().min(1).max(100),
  email: z.string().email(),
});

export async function updateProfile(formData: FormData) {
  const validatedFields = updateProfileSchema.safeParse({
    name: formData.get('name'),
    email: formData.get('email'),
  });

  if (!validatedFields.success) {
    return {
      errors: validatedFields.error.flatten().fieldErrors,
    };
  }

  const { name, email } = validatedFields.data;

  try {
    await prisma.user.update({
      where: { id: getCurrentUserId() },
      data: { name, email },
    });
  } catch (error) {
    return { error: '更新个人资料失败' };
  }

  revalidatePath('/dashboard/settings');
  redirect('/dashboard');
}

使用 Server Action 的表单

// app/dashboard/settings/page.tsx
import { updateProfile } from '@/lib/actions/user-actions';
import { SubmitButton } from '@/components/ui/submit-button';

export default function SettingsPage() {
  return (
    <form action={updateProfile} className="space-y-4">
      <div>
        <label htmlFor="name">姓名</label>
        <input
          id="name"
          name="name"
          type="text"
          required
          className="w-full border rounded px-3 py-2"
        />
      </div>

      <div>
        <label htmlFor="email">邮箱</label>
        <input
          id="email"
          name="email"
          type="email"
          required
          className="w-full border rounded px-3 py-2"
        />
      </div>

      <SubmitButton>更新个人资料</SubmitButton>
    </form>
  );
}

中间件

// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export function middleware(request: NextRequest) {
  const token = request.cookies.get('auth-token');

  if (!token && request.nextUrl.pathname.startsWith('/dashboard')) {
    return NextResponse.redirect(new URL('/login', request.url));
  }

  const response = NextResponse.next();

  // 添加安全头
  response.headers.set('X-Frame-Options', 'DENY');
  response.headers.set('X-Content-Type-Options', 'nosniff');

  return response;
}

export const config = {
  matcher: ['/dashboard/:path*', '/api/:path*'],
};

API 路由处理器

// app/api/users/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { prisma } from '@/lib/db/prisma';

export async function GET(request: NextRequest) {
  const searchParams = request.nextUrl.searchParams;
  const page = parseInt(searchParams.get('page') ?? '1');
  const limit = parseInt(searchParams.get('limit') ?? '10');

  const users = await prisma.user.findMany({
    skip: (page - 1) * limit,
    take: limit,
    select: {
      id: true,
      name: true,
      email: true,
    },
  });

  return NextResponse.json({ users, page, limit });
}

export async function POST(request: NextRequest) {
  const body = await request.json();

  const user = await prisma.user.create({
    data: body,
  });

  return NextResponse.json(user, { status: 201 });
}

缓存策略

带重新验证的静态生成

// 每小时重新验证一次
export const revalidate = 3600;

export default async function Page() {
  const data = await fetchData();
  return <div>{/* 内容 */}</div>;
}

按需重新验证

// app/api/revalidate/route.ts
import { revalidatePath, revalidateTag } from 'next/cache';
import { NextRequest, NextResponse } from 'next/server';

export async function POST(request: NextRequest) {
  const { path, tag, secret } = await request.json();

  if (secret !== process.env.REVALIDATION_SECRET) {
    return NextResponse.json({ error: '无效密钥' }, { status: 401 });
  }

  if (tag) {
    revalidateTag(tag);
  } else if (path) {
    revalidatePath(path);
  }

  return NextResponse.json({ revalidated: true });
}

依赖项

{
  "dependencies": {
    "next": "^15.0.0",
    "react": "^19.0.0",
    "react-dom": "^19.0.0"
  },
  "devDependencies": {
    "@types/node": "^22.0.0",
    "@types/react": "^19.0.0",
    "@types/react-dom": "^19.0.0",
    "typescript": "^5.7.0"
  }
}

工作流程

  1. 创建项目结构 - 设置 App Router 目录
  2. 配置布局 - 根布局和嵌套布局
  3. 实现页面 - 服务器组件和客户端组件
  4. 添加 Server Actions - 表单处理和变更
  5. 配置中间件 - 认证和安全
  6. 设置 API 路由 - REST 或 tRPC 端点
  7. 优化缓存 - 静态和动态策略
  8. 部署到 Vercel - 边缘和无服务器配置

应用的最佳实践

  • 使用 React Server Components 的 App Router
  • TypeScript 严格模式
  • 用于变更的 Server Actions
  • 适当的加载和错误状态
  • 使用 next/image 进行图像优化
  • 使用 next/font 进行字体优化
  • 用于 SEO 的元数据 API
  • 边缘兼容代码

参考资料

目标流程

  • nextjs-全栈开发
  • 服务器组件架构
  • api-路由实现
  • 认证设置
  • 部署优化