⚡ Next.js 完整学习路径

📌 关于 Next.js: Next.js 是由 Vercel 开发的 React 全栈框架,支持服务端渲染(SSR)、静态站点生成(SSG)、增量静态再生成(ISR)等多种渲染模式。被世界上一些最大的公司使用,可创建高质量的 Web 应用程序。

📋 学习路线图

1

环境准备(1-2 天)

Node.js 18.17+、VS Code + React 扩展、包管理器(npm/pnpm/bun)

2

基础入门(3-5 天)

项目创建、目录结构、路由系统、组件开发

3

核心概念(5-7 天)

数据获取、缓存、服务端组件、客户端组件

4

进阶实战(7-10 天)

API 路由、中间件、认证系统、性能优化

5

项目实战(10-15 天)

完整项目开发、最佳实践、部署上线

🛠️ 第一步:环境准备

前置要求

💡 推荐配置: 使用 pnpm 作为包管理器,速度更快、磁盘占用更少。安装命令:npm install -g pnpm

📦 第二步:创建项目

1️⃣创建新项目

# 使用 npx (推荐)
npx create-next-app@latest <project-name>

# 使用 pnpm
pnpm create next-app@latest <project-name>

# 使用 bun
bunx create-next-app@latest <project-name>

2️⃣进入项目目录

cd <project-name>

3️⃣启动开发服务器

# 使用 npm
npm run dev

# 使用 pnpm
pnpm dev

# 使用 bun
bun run dev

开发服务器将在 http://localhost:3000 启动

📁 第三步:理解目录结构

目录/文件 作用 说明
app/ App Router 目录 Next.js 13+ 推荐结构
app/page.tsx 首页组件 路由 / 的页面
app/layout.tsx 根布局 所有页面共享的布局
app/globals.css 全局样式 全局 CSS 样式文件
components/ 组件目录 可复用的 React 组件
lib/ 工具库 工具函数、配置等
public/ 静态资源 图片、字体等静态文件
next.config.ts 配置文件 Next.js 项目配置
package.json 项目配置 依赖和脚本定义

⚡ 第四步:核心概念

1. App Router vs Pages Router

Next.js 13+ 推荐使用 App Router(基于 React Server Components):

💡 对比:
  • App Router - 新一代路由系统,支持服务端组件、嵌套布局、并行路由
  • Pages Router - 传统路由系统,基于文件的路由,简单易用
新项目推荐使用 App Router!

2. 服务端组件 vs 客户端组件

Next.js 的核心特性之一:

app/page.tsx - 服务端组件(默认)
// 服务端组件 - 默认
// 可以直接在服务端执行数据库查询、API 调用

export default async function Page() {
  const data = await fetch('https://api.example.com/data')
  
  return (
    <main>
      <h1>服务端渲染的内容</h1>
      <p>{data.message}</p>
    </main>
  )
}
app/components/Counter.tsx - 客户端组件
'use client'

// 客户端组件 - 需要交互状态时使用
import { useState } from 'react'

export function Counter() {
  const [count, setCount] = useState(0)
  
  return (
    <button onClick={() => setCount(count + 1)}>
      Count: {count}
    </button>
  )
}
💡 使用规则:
  • 默认使用服务端组件(更好的性能、SEO)
  • 需要 useState、useEffect、事件处理时,添加 'use client'
  • 服务端组件可以导入客户端组件,反之不行

3. 数据获取

Next.js 提供多种数据获取方式:

app/page.tsx - 服务端数据获取
// 服务端组件中直接异步获取数据
export default async function Page() {
  // 自动缓存,可配置
  const data = await fetch('https://api.example.com/data', {
    cache: 'force-cache' // 或 'no-store' 禁用缓存
  })
  
  return <div>{data.title}</div>
}

// 或使用 async/await 模式
async function getData() {
  const res = await fetch('https://api.example.com/data')
  return res.json()
}

export default async function Page() {
  const data = await getData()
  return <div>{data.title}</div>
}

4. 路由系统

基于文件系统的路由(App Router):

路由示例

app/
├── page.tsx              → /
├── about/
│   └── page.tsx          → /about
├── blog/
│   ├── page.tsx          → /blog
│   └── [slug]/
│       └── page.tsx      → /blog/:slug (动态路由)
├── dashboard/
│   ├── layout.tsx        → 仪表盘布局
│   └── page.tsx          → /dashboard
└── api/
    └── route.ts          → API 路由

5. 布局(Layouts)

在多个页面之间共享 UI:

app/layout.tsx - 根布局
export const metadata = {
  title: 'My Next.js App',
  description: 'Generated by Next.js',
}

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="zh-CN">
      <body>
        <nav>
          <a href="/">首页</a>
          <a href="/about">关于</a>
          <a href="/blog">博客</a>
        </nav>
        {children}
        <footer>© 2026 My App</footer>
      </body>
    </html>
  )
}

6. API 路由

在 Next.js 中创建 API 端点:

app/api/users/route.ts
import { NextResponse } from 'next/server'

// GET 请求
export async function GET() {
  const users = [
    { id: 1, name: 'Alice' },
    { id: 2, name: 'Bob' }
  ]
  
  return NextResponse.json(users)
}

// POST 请求
export async function POST(request: Request) {
  const body = await request.json()
  
  // 处理创建用户的逻辑
  const newUser = { id: 3, ...body }
  
  return NextResponse.json(newUser, { status: 201 })
}
app/api/users/[id]/route.ts - 动态路由
import { NextResponse } from 'next/server'

// GET /api/users/1
export async function GET(
  request: Request,
  { params }: { params: { id: string } }
) {
  const { id } = params
  
  // 根据 ID 获取用户
  const user = { id, name: 'User ' + id }
  
  return NextResponse.json(user)
}

// DELETE /api/users/1
export async function DELETE(
  request: Request,
  { params }: { params: { id: string } }
) {
  const { id } = params
  
  // 删除用户的逻辑
  
  return NextResponse.json({ success: true })
}

7. 中间件(Middleware)

在请求到达页面之前运行代码:

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

export function middleware(request: NextRequest) {
  // 检查用户认证
  const token = request.cookies.get('token')
  
  if (!token && request.nextUrl.pathname.startsWith('/dashboard')) {
    return NextResponse.redirect(new URL('/login', request.url))
  }
  
  // 添加自定义 header
  const response = NextResponse.next()
  response.headers.set('x-custom-header', 'value')
  
  return response
}

// 配置中间件匹配的路径
export const config = {
  matcher: ['/dashboard/:path*', '/api/:path*']
}

🎯 第五步:实战项目 - 博客系统

项目结构

my-nextjs-blog/
├── app/
│   ├── blog/
│   │   ├── [slug]/
│   │   │   └── page.tsx    # 博客详情页
│   │   └── page.tsx        # 博客列表页
│   ├── about/
│   │   └── page.tsx        # 关于页
│   ├── api/
│   │   └── posts/
│   │       └── route.ts    # 博客 API
│   ├── components/
│   │   ├── BlogCard.tsx    # 博客卡片
│   │   └── NavBar.tsx      # 导航栏
│   ├── globals.css         # 全局样式
│   ├── layout.tsx          # 根布局
│   └── page.tsx            # 首页
├── lib/
│   └── posts.ts            # 博客数据工具
├── public/
│   └── images/             # 静态图片
└── next.config.ts          # 配置文件

示例代码

lib/posts.ts
import fs from 'fs'
import path from 'path'
import matter from 'gray-matter'

const postsDirectory = path.join(process.cwd(), 'posts')

export function getSortedPostsData() {
  const fileNames = fs.readdirSync(postsDirectory)
  const allPostsData = fileNames.map(fileName => {
    const id = fileName.replace(/\.md$/, '')
    const fullPath = path.join(postsDirectory, fileName)
    const fileContents = fs.readFileSync(fullPath, 'utf8')
    const { data } = matter(fileContents)
    
    return {
      id,
      title: data.title,
      date: data.date,
      excerpt: data.excerpt
    }
  })
  
  return allPostsData.sort((a, b) => {
    return a.date > b.date ? -1 : 1
  })
}

export function getPostData(id: string) {
  const fullPath = path.join(postsDirectory, `${id}.md`)
  const fileContents = fs.readFileSync(fullPath, 'utf8')
  const { data, content } = matter(fileContents)
  
  return {
    id,
    title: data.title,
    date: data.date,
    content
  }
}
app/blog/page.tsx
import { getSortedPostsData } from '@/lib/posts'
import BlogCard from '@/components/BlogCard'

export default function BlogPage() {
  const posts = getSortedPostsData()
  
  return (
    <main>
      <h1>博客文章</h1>
      <div className="grid">
        {posts.map(post => (
          <BlogCard key={post.id} post={post} />
        ))}
      </div>
    </main>
  )
}
app/blog/[slug]/page.tsx
import { getPostData } from '@/lib/posts'
import { notFound } from 'next/navigation'

export default async function BlogPost({
  params
}: {
  params: { slug: string }
}) {
  const post = getPostData(params.slug)
  
  if (!post) {
    notFound()
  }
  
  return (
    <article>
      <h1>{post.title}</h1>
      <time>{post.date}</time>
      <div dangerouslySetInnerHTML={{ __html: post.content }} />
    </article>
  )
}

🚀 第六步:构建与部署

生产构建

# 构建项目
npm run build

# 启动生产服务器
npm run start

部署选项

  • Vercel - 一键部署,Next.js 官方推荐(最简单)
  • Netlify - 支持 Next.js 部署
  • Docker - 容器化部署
  • 传统服务器 - Node.js 进程托管
💡 推荐: 使用 Vercel 部署 Next.js 应用最简单,零配置自动部署。GitHub 仓库连接后自动构建和部署!

📚 学习资源

✅ 学完本教程后,你将能够:

  • ✅ 创建和配置 Next.js 项目
  • ✅ 理解 App Router 和路由系统
  • ✅ 掌握服务端组件和客户端组件
  • ✅ 实现数据获取和缓存
  • ✅ 开发 API 路由和中间件
  • ✅ 构建并部署生产应用

📖 原文链接

本文档内容整理自 Next.js 官方文档:

📌 Next.js - The React Framework
由 Vercel 开发和维护 · 被世界顶级公司使用

← 返回文档中心