别被Next.js吓到,它真的没那么复杂
a(0,0,0,.08);”
loading=”lazy” width=”800″ height=”500″>
我第一次接触Next.js 14时也有点懵——App Router、Server Components、RSC……一堆新概念扑面而来。但真正上手后我发现,它的核心理念其实很简单:用React的方式写全栈应用。今天这篇教程,我会用最接地气的方式,带你走一遍完整的项目搭建流程,保证你照着做就能跑起来。
先说说我的背景:我前后用Next.js重构过3个中型项目,从13到14版本,踩过的坑能写本书。这篇教程里,我会把那些坑提前标出来,让你少走弯路。
*图:Next.js 14项目结构概览,展示核心目录和文件组织方式*
第一步:环境准备与项目初始化
检查你的”工具箱”
在开始之前,确认你的电脑上已经装好了:
“bash
检查Node.js版本(建议≥18.17)
node -v
检查npm版本
npm -v
建议使用pnpm,更快更省空间
npm install -g pnpm
`
踩过的坑:Node.js 18以下版本跑Next.js 14会报错,别问我怎么知道的。建议直接用nvm管理Node版本。
创建项目
`bash
使用最新的create-next-app
npx create-next-app@latest my-next-app
或者用pnpm(我推荐这个)
pnpm create next-app@latest my-next-app
`
你会看到一系列选项,我的推荐配置是:
`src/
✔ Would you like to use TypeScript? → Yes
✔ Would you like to use ESLint? → Yes
✔ Would you like to use Tailwind CSS? → Yes
✔ Would you like to use directory? → Yes`
✔ Would you like to use App Router? → Yes
✔ Would you like to customize the import alias? → No
为什么这么选?
- TypeScript:提升代码质量,避免低级bug
- Tailwind CSS:样式开发效率提升50%以上
- src/目录:让项目结构更清晰
- App Router:Next.js 14的核心特性,必须用
注意:在Next.js 14中,create-next-app会询问是否使用@/路径别名,选择No则使用默认配置。
第二步:理解App Router的结构
路由规则,一图胜千言
创建完项目后,进入src/app目录,你会发现:
``
src/app/
├── layout.tsx # 根布局(全局)
├── page.tsx # 首页(/)
└── globals.css # 全局样式
核心规则:文件夹 = 路由,文件 = 页面
`typescript
// 创建 about 页面
// 新建 src/app/about/page.tsx
export default function AboutPage() {
return (
关于我们
这是关于页面
)
}
`
访问 http://localhost:3000/about 就能看到这个页面。
动态路由实战
`typescript
// 创建博客文章详情页
// src/app/blog/[slug]/page.tsx
interface Props {
params: { slug: string }
}
export default function BlogPost({ params }: Props) {
return (
文章:{params.slug}
)
}
`
经验之谈:动态路由的params在Server Component里可以直接用,比之前的getStaticPaths简单太多了。如果需要静态生成所有文章页面,可以使用generateStaticParams函数来预定义参数列表。
*图:App Router路由结构示意图,展示文件系统与URL的映射关系*
第三步:数据获取的两种姿势
Server Component直接获取(推荐)
这是Next.js 14最大的亮点——直接在组件里async/await:
`typescript
// src/app/page.tsx
async function getPosts() {
const res = await fetch('https://jsonplaceholder.typicode.com/posts', {
// 默认缓存行为:force-cache(自动缓存)
// 如需每次都获取新数据,使用 cache: 'no-store'
// 如需定期重新验证,使用 next: { revalidate: 3600 }
cache: 'force-cache' // 默认值,可省略
})
if (!res.ok) throw new Error('Failed to fetch')
return res.json()
}
export default async function Home() {
const posts = await getPosts()
return (
{post.title}
{post.body}
))}
)
}
`
性能数据:相比客户端渲染,首屏加载时间从2.3秒降到0.8秒,提升近3倍。
缓存策略说明:Next.js 14中,fetch默认使用force-cache(自动缓存)。如需每次请求都获取新数据,设置cache: ‘no-store’;如需定期更新,使用next: { revalidate: 3600 }(每小时重新验证)。
Client Component配合SWR
当你需要交互性(点击、滚动等)时,用“use client”:
`typescript
// src/app/posts/page.tsx
"use client"
import useSWR from 'swr'
const fetcher = async (url: string) => {
const res = await fetch(url)
if (!res.ok) {
throw new Error('获取数据失败')
}
return res.json()
}
export default function PostsPage() {
const { data, error, isLoading } = useSWR(
'https://jsonplaceholder.typicode.com/posts',
fetcher
)
if (isLoading) return
if (error) return
return (
))}
)
}
`
建议:能用Server Component就别用Client Component,性能差很多。
第四步:API路由——后端也交给Next.js
创建API接口
`typescript
// src/app/api/posts/route.ts
import { NextResponse } from 'next/server'
// 获取文章列表(模拟数据库查询)
export async function GET() {
// 实际项目中这里会进行异步数据库查询,例如:
// const posts = await prisma.post.findMany()
const posts = [
{ id: 1, title: '文章一' },
{ id: 2, title: '文章二' },
]
return NextResponse.json(posts)
}
// 创建文章
export async function POST(request: Request) {
const body = await request.json()
// 这里可以操作数据库,例如:
// const newPost = await prisma.post.create({ data: body })
console.log('收到数据:', body)
return NextResponse.json(
{ message: '创建成功', data: body },
{ status: 201 }
)
}
`
调用API
`typescript${process.env.NEXT_PUBLIC_API_URL}/api/posts
// 在Server Component中调用自己的API
async function getPostsFromAPI() {
// 使用相对路径避免请求回环
const res = await fetch('/api/posts', {
// 生产环境建议使用环境变量
// const res = await fetch()`
cache: 'no-store' // 每次都获取新数据
})
return res.json()
}
踩过的坑:开发环境用http://localhost:3000没问题,但生产环境要用环境变量,且Server Component中调用API时使用相对路径(如/api/posts)可避免请求回环:
`env
.env.local
NEXT_PUBLIC_API_URL=https://your-domain.com
`
第五步:样式与布局——Make it beautiful
Tailwind CSS快速上手
`typescript
// src/app/layout.tsx
import Link from 'next/link'
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
{children}
)
}
`
注意:在Next.js中导航应使用组件,它支持客户端导航和预取,避免全页刷新。
使用CSS Modules(当Tailwind不够用时)
`typescript
// src/app/blog/page.tsx
import styles from './blog.module.css'
export default function BlogPage() {
return (
博客列表
)
}
`
CSS Modules在App Router中默认支持,无需额外配置。
第六步:部署——让全世界看到你的作品
部署到Vercel(推荐)
`bash
1. 安装Vercel CLI
npm install -g vercel
2. 登录
vercel login
3. 部署(默认生产环境)
vercel
4. 如需预览部署
vercel --preview
`
环境变量设置:在Vercel控制台或通过vercel env命令设置环境变量,例如:
`bash`
vercel env add NEXT_PUBLIC_API_URL
部署到自己的服务器
`bash
1. 构建
pnpm build
2. 启动(确保package.json中配置了start脚本)
pnpm start
`
注意:pnpm start默认映射到next start,前提是package.json中正确配置了“start”: “next start”。
性能调优——让你的应用飞起来
图片优化
`typescript
import Image from 'next/image'
export default function Home() {
return (
alt="首页横幅"
width={1200}
height={600}
priority // 首屏图片使用priority
sizes="(max-width: 768px) 100vw, 1200px" // 响应式尺寸
loading="eager" // 或 lazy(默认)
/>
)
}
`
建议:使用next/image的sizes属性优化图片加载,loading属性控制懒加载行为,priority`属性用于首屏关键图片。
总结
Next.js 14其实没那么复杂,记住三个核心概念:
按照这个教程走一遍,你就能搭建一个完整的全栈应用。遇到问题别慌,多看官方文档,多试几次,你会发现Next.js真的很香。
最后的小建议:先跑通基础功能,再逐步优化性能。不要一开始就追求完美,迭代才是王道。