mcpField
N
nextjs-project-manager

nextjs-project-manager

github.com/jmsktm开发10202 次安装40 周前更新
代码仓库

关于 nextjs-project-manager

nextjs-project-manager 是用于构建和维护 Next.js 14+ App Router 应用的技能,面向 Next.js 开发者。它提供路由、组件、数据获取、Server Actions 和性能优化方面的模式。

主要功能

  1. 01App Router 路由与布局模式
  2. 02Server 与 Client Component 指引
  3. 03数据获取与 Server Actions
  4. 04API 路由与中间件
  5. 05加载、错误和元数据模式
  6. 06性能优化指引

适用场景

  1. 01创建路由和共享布局
  2. 02使用 Server Actions 构建表单
  3. 03调试 Next.js 特定错误
  4. 04提升应用性能

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/jmsktm/claude-settings --skill nextjs-project-manager

安装后在 Claude Code 中输入/nextjs-project-manager确认已加载。

详细介绍

Next.js 项目管理技能

概述

此技能可帮助你使用 App Router 构建适用于生产环境的 Next.js 14+ 应用。在处理路由、组件、Server Actions、数据获取或任何 Next.js 特定模式时使用此技能。

核心原则

1. 优先使用 App Router
  • 所有路由都放在 src/app/ 目录中
  • 使用 page.tsx 定义路由,使用 layout.tsx 定义共享布局
  • 默认使用 Server Components,必要时使用 Client Components
  • 使用 (group) 路由组进行组织
2. Server Components 与 Client Components

Server Components(默认):

  • 无需添加 "use client" 指令
  • 可直接使用 async/await
  • 可直接访问数据库/后端
  • 性能更佳(发送到客户端的 JS 更少)
  • 不能使用 hooks 或浏览器 API

Client Components("use client"):

  • 在需要以下功能时使用:
    • 状态(useState、useReducer)
    • 副作用(useEffect)
    • 事件处理程序(onClick、onChange)
    • 浏览器 API(localStorage、window)
    • 使用 hooks 的第三方库
3. 数据获取模式

Server Components:

// Direct async fetch in component
export default async function Page() {
  const data = await fetch('https://api.example.com/data')
  const json = await data.json()
  return <div>{json.title}</div>
}

Client Components:

'use client'
import { useEffect, useState } from 'react'

export default function Page() {
  const [data, setData] = useState(null)

  useEffect(() => {
    fetch('/api/data')
      .then(res => res.json())
      .then(setData)
  }, [])

  return <div>{data?.title}</div>
}
4. Server Actions

使用 Server Actions 处理表单提交和数据变更:

// app/actions.ts
'use server'

export async function createItem(formData: FormData) {
  const title = formData.get('title')
  // Database operation
  await db.insert({ title })
  revalidatePath('/items')
  redirect('/items')
}

// app/form.tsx
'use client'
import { createItem } from './actions'

export function Form() {
  return (
    <form action={createItem}>
      <input name="title" />
      <button type="submit">Create</button>
    </form>
  )
}

常见模式

路由结构
src/app/
├── (auth)/
│   ├── login/
│   │   └── page.tsx
│   └── signup/
│       └── page.tsx
├── (dashboard)/
│   ├── layout.tsx          # Shared dashboard layout
│   ├── page.tsx            # Dashboard home
│   └── settings/
│       └── page.tsx
├── api/
│   └── endpoint/
│       └── route.ts        # API routes
├── layout.tsx              # Root layout
└── page.tsx                # Home page
布局
// app/(dashboard)/layout.tsx
import { Sidebar } from '@/components/sidebar'

export default function DashboardLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <div className="flex">
      <Sidebar />
      <main className="flex-1">{children}</main>
    </div>
  )
}
加载状态
// app/dashboard/loading.tsx
export default function Loading() {
  return <div>Loading...</div>
}
错误处理
// app/dashboard/error.tsx
'use client'

export default function Error({
  error,
  reset,
}: {
  error: Error
  reset: () => void
}) {
  return (
    <div>
      <h2>Something went wrong!</h2>
      <button onClick={reset}>Try again</button>
    </div>
  )
}
元数据
// app/page.tsx
import type { Metadata } from 'next'

export const metadata: Metadata = {
  title: 'Page Title',
  description: 'Page description',
}

export default function Page() {
  return <div>Content</div>
}

API 路由

// app/api/items/route.ts
import { NextRequest, NextResponse } from 'next/server'

export async function GET(request: NextRequest) {
  const items = await db.getItems()
  return NextResponse.json({ items })
}

export async function POST(request: NextRequest) {
  const body = await request.json()
  const item = await db.createItem(body)
  return NextResponse.json({ item }, { status: 201 })
}

动态路由

// app/posts/[id]/page.tsx
export default function Post({ params }: { params: { id: string } }) {
  return <div>Post {params.id}</div>
}

// Generate static params
export async function generateStaticParams() {
  const posts = await getPosts()
  return posts.map((post) => ({ id: post.id }))
}

中间件

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

export function middleware(request: NextRequest) {
  // Check auth, redirect, rewrite, etc.
  return NextResponse.next()
}

export const config = {
  matcher: '/dashboard/:path*',
}

环境变量

// Access in Server Components or Server Actions
const apiKey = process.env.API_KEY

// Access in Client Components (must be prefixed with NEXT_PUBLIC_)
const publicKey = process.env.NEXT_PUBLIC_API_KEY

最佳实践检查清单

  • 默认使用 Server Components
  • 仅在必要时添加 "use client"
  • 使用 Server Actions 处理数据变更
  • 使用 loading.tsx 实现加载状态
  • 使用 error.tsx 实现错误边界
  • 使用路由组进行组织
  • 为所有页面添加元数据
  • 使用 TypeScript 确保类型安全
  • 实现适当的错误处理
  • 使用中间件进行身份验证检查
  • 使用 next/image 优化图像
  • 使用动态导入加载大型组件

调试技巧

  1. Hydration 错误:检查服务器端与客户端是否不匹配
  2. "use client" 错误:使用 hooks 的组件缺少指令
  3. 无法访问浏览器 API:移至 Client Component
  4. 数据未更新:使用 revalidatePath() 或 revalidateTag()
  5. 构建错误:检查是否存在缺少正确类型标注的异步组件

性能优化

  • 使用 React Suspense 处理加载状态
  • 使用 loading.tsx 实现流式传输
  • 使用动态导入进行代码拆分
  • 使用 next/image 优化图像
  • 使用 next/font 优化字体
  • 实现 ISR(增量静态再生)
  • 使用 fetch 选项进行缓存

何时使用此技能

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

  • 创建新路由或页面
  • 设置布局
  • 使用 Server Actions 实现表单
  • 调试 Next.js 特定错误
  • 优化性能
  • 设置中间件
  • 创建 API 路由
  • 处理元数据

评论

支持 Markdown