Next.js 最佳实践 ✨
🎯 概述
遵循最佳实践可以提高代码质量、性能和可维护性。
📦 项目结构
推荐结构
app/
├── (auth)/
│ ├── login/
│ └── register/
├── (dashboard)/
│ ├── layout.tsx
│ └── page.tsx
├── api/
├── layout.tsx
└── page.tsx
components/
├── ui/
├── forms/
└── layouts/
lib/
├── utils.ts
├── db.ts
└── auth.ts
public/
├── images/
└── fonts/🚀 性能优化
1. 使用 Server Components
tsx
// ✅ 默认使用服务端组件
export default async function Page() {
const data = await getData()
return <div>{data.title}</div>
}
// ❌ 避免不必要的客户端组件
'use client'
export default function Page() {
return <div>静态内容</div>
}2. 代码分割
tsx
import dynamic from 'next/dynamic'
const HeavyComponent = dynamic(() => import('@/components/Heavy'), {
loading: () => <Skeleton />,
ssr: false,
})3. 图片优化
tsx
import Image from 'next/image'
<Image
src="/hero.jpg"
alt="Hero"
width={1200}
height={600}
priority
placeholder="blur"
/>📝 代码质量
1. TypeScript
tsx
// 使用类型定义
interface User {
id: string
name: string
email: string
}
async function getUser(id: string): Promise<User> {
const res = await fetch(`/api/users/${id}`)
return res.json()
}2. 错误处理
tsx
// app/page.tsx
export default async function Page() {
try {
const data = await getData()
return <div>{data.title}</div>
} catch (error) {
return <ErrorComponent error={error} />
}
}3. 数据验证
tsx
import { z } from 'zod'
const schema = z.object({
email: z.string().email(),
password: z.string().min(8),
})
export async function POST(request: Request) {
const body = await request.json()
const result = schema.safeParse(body)
if (!result.success) {
return Response.json({ error: result.error }, { status: 400 })
}
// 处理有效数据
}🎨 SEO 优化
1. 元数据
tsx
export const metadata = {
title: '页面标题',
description: '页面描述',
openGraph: {
title: '页面标题',
description: '页面描述',
images: ['/og-image.jpg'],
},
}2. 语义化 HTML
tsx
<article>
<header>
<h1>文章标题</h1>
<time dateTime="2024-01-01">2024年1月1日</time>
</header>
<section>
<p>文章内容</p>
</section>
</article>📊 安全性
1. 环境变量
bash
# .env.local
DATABASE_URL="postgresql://..."
JWT_SECRET="your-secret"
# 客户端变量使用 NEXT_PUBLIC_ 前缀
NEXT_PUBLIC_API_URL="https://api.example.com"2. API 保护
tsx
// middleware.ts
export function middleware(request: Request) {
const token = request.headers.get('Authorization')
if (!token) {
return Response.json({ error: 'Unauthorized' }, { status: 401 })
}
return NextResponse.next()
}3. 输入清理
tsx
import DOMPurify from 'isomorphic-dompurify'
const clean = DOMPurify.sanitize(userInput)📚 开发体验
1. ESLint 配置
json
{
"extends": "next/core-web-vitals",
"rules": {
"no-console": "warn",
"@typescript-eslint/no-unused-vars": "error"
}
}2. Prettier 配置
json
{
"semi": false,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "es5"
}3. Git Hooks
bash
npm install -D husky lint-staged
# package.json
{
"lint-staged": {
"*.{js,jsx,ts,tsx}": ["eslint --fix", "prettier --write"]
}
}🔧 测试
1. 单元测试
tsx
import { render, screen } from '@testing-library/react'
import Component from './Component'
test('renders component', () => {
render(<Component />)
expect(screen.getByText('Hello')).toBeInTheDocument()
})2. E2E 测试
ts
import { test, expect } from '@playwright/test'
test('home page', async ({ page }) => {
await page.goto('/')
await expect(page.getByRole('heading')).toBeVisible()
})🔗 相关资源
恭喜! 你已经完成了 Next.js 教程的学习。继续实践,构建出色的应用!