1. 使用 Sentry 進行錯誤追蹤
npx @sentry/wizard@latest -i nextjs
// sentry.client.config.ts
import * as Sentry from '@sentry/nextjs';
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
tracesSampleRate: 0.1, // 10% of transactions
replaysSessionSampleRate: 0.1,
replaysOnErrorSampleRate: 1.0,
integrations: [
Sentry.replayIntegration(),
Sentry.feedbackIntegration({ colorScheme: 'system' }),
],
});
// app/global-error.tsx
'use client';
import * as Sentry from '@sentry/nextjs';
import { useEffect } from 'react';
export default function GlobalError({ error, reset }: {
error: Error & { digest?: string };
reset: () => void;
}) {
useEffect(() => {
Sentry.captureException(error);
}, [error]);
return (
<html>
<body>
<h2>Đã xảy ra lỗi!</h2>
<button onClick={reset}>Thử lại</button>
</body>
</html>
);
}
2. 日誌記錄最佳實踐
// lib/logger.ts
import pino from 'pino';
export const logger = pino({
level: process.env.LOG_LEVEL || 'info',
transport: process.env.NODE_ENV === 'development'
? { target: 'pino-pretty' }
: undefined,
formatters: {
level(label) { return { level: label }; },
},
base: {
env: process.env.NODE_ENV,
service: 'nextjs-app',
},
});
// Sử dụng
logger.info({ userId: '123', action: 'login' }, 'User logged in');
logger.error({ err: error, requestId }, 'Request failed');
3. 安全標頭
// next.config.ts
const securityHeaders = [
{
key: 'X-DNS-Prefetch-Control',
value: 'on',
},
{
key: 'Strict-Transport-Security',
value: 'max-age=63072000; includeSubDomains; preload',
},
{
key: 'X-Content-Type-Options',
value: 'nosniff',
},
{
key: 'X-Frame-Options',
value: 'DENY',
},
{
key: 'X-XSS-Protection',
value: '1; mode=block',
},
{
key: 'Referrer-Policy',
value: 'strict-origin-when-cross-origin',
},
{
key: 'Permissions-Policy',
value: 'camera=(), microphone=(), geolocation=()',
},
{
key: 'Content-Security-Policy',
value: "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline';",
},
];
const config = {
async headers() {
return [{ source: '/:path*', headers: securityHeaders }];
},
};
4. 健康檢查
// app/api/health/route.ts
import { NextResponse } from 'next/server';
import { db } from '@/lib/db';
export async function GET() {
try {
// Check database
await db.$queryRaw`SELECT 1`;
return NextResponse.json({
status: 'healthy',
timestamp: new Date().toISOString(),
uptime: process.uptime(),
checks: {
database: 'ok',
memory: process.memoryUsage(),
},
});
} catch (error) {
return NextResponse.json(
{ status: 'unhealthy', error: 'Database connection failed' },
{ status: 503 }
);
}
}
// app/api/ready/route.ts — Kubernetes readiness probe
export async function GET() {
// Check all external dependencies
const checks = await Promise.allSettled([
db.$queryRaw`SELECT 1`,
fetch(process.env.REDIS_URL + '/ping'),
]);
const allHealthy = checks.every(c => c.status === 'fulfilled');
return NextResponse.json(
{ ready: allHealthy },
{ status: allHealthy ? 200 : 503 }
);
}
5. 速率限制
// middleware.ts — Simple rate limiting
import { NextRequest, NextResponse } from 'next/server';
const rateLimit = new Map<string, { count: number; resetTime: number }>();
export function middleware(request: NextRequest) {
if (!request.nextUrl.pathname.startsWith('/api')) {
return NextResponse.next();
}
const ip = request.headers.get('x-forwarded-for') || 'unknown';
const now = Date.now();
const windowMs = 60 * 1000; // 1 minute
const maxRequests = 100;
const record = rateLimit.get(ip);
if (!record || now > record.resetTime) {
rateLimit.set(ip, { count: 1, resetTime: now + windowMs });
return NextResponse.next();
}
if (record.count >= maxRequests) {
return NextResponse.json(
{ error: 'Too many requests' },
{ status: 429, headers: { 'Retry-After': '60' } }
);
}
record.count++;
return NextResponse.next();
}
6. 生產檢查表
| 類別 | 專案 | 狀態 |
|---|---|---|
| 安全性 | 配置的安全標頭 | ⑨ |
| 安全性 | CSRF 保護(伺服器操作) | ⑨ |
| 安全性 | 已啟用速率限制 | ⑨ |
| 安全性 | 環境變數已驗證 | ⑨ |
| 效能 | 優化影像(下一張/影像) | ⑨ |
| 效能 | 優化字體(下一個/字體) | ⑨ |
| 效能 | 捆綁包分析與最佳化 | ⑨ |
| 監控 | 錯誤跟踪(哨兵) | ⑨ |
| 監控 | 結構化日誌記錄 | ⑨ |
| 監控 | 健康檢查端點 | ⑨ |
| 部署 | Docker 多階段建置 | ⑨ |
| 部署 | CI/CD 管道 | ⑨ |
| 部署 | CI 中的資料庫遷移 | ⑨ |
| 搜尋引擎優化 | 網站地圖和 robots.txt | ⑨ |
| 搜尋引擎優化 | OpenGraph 和結構化數據 | ⑨ |
🎉 恭喜! 您已完成從基礎到進階的 React 和 Next.js 課程。將您的知識應用到實際項目中!