🙋 高效的开发体验是提升生产力的关键。Next.js 15 带来了哪些开发工具改进?
Turbopack#
Next.js 15 将 Turbopack 设为开发模式的默认打包器。它使用 Rust 编写,比 Webpack 快得多。
默认启用#
# 开发模式自动使用 Turbopackpnpm dev
# 输出显示使用的打包器# ▲ Next.js 15.x# - Local: http://localhost:3000# - Turbopack (default)性能对比#
| 操作 | Webpack | Turbopack | 提升 |
|---|---|---|---|
| 冷启动 | 12s | 2s | 6x |
| HMR | 500ms | 50ms | 10x |
| 路由切换 | 200ms | 30ms | 6x |
数据来自中型项目(~500 组件)
回退到 Webpack#
如果项目有自定义 Webpack 配置且无法迁移:
# 使用 Webpackpnpm dev --webpack或在 package.json 中配置:
{ "scripts": { "dev": "next dev --webpack" }}Turbopack 配置#
// Next.js 15.ximport type { NextConfig } from 'next'
const nextConfig: NextConfig = { turbopack: { // 自定义文件处理规则 rules: { '*.svg': { loaders: ['@svgr/webpack'], as: '*.js', }, }, // 模块别名 resolveAlias: { 'old-package': 'new-package', }, // 文件扩展名解析顺序 resolveExtensions: ['.tsx', '.ts', '.jsx', '.js', '.json'], },}
export default nextConfigFast Refresh#
Fast Refresh 是 Next.js 的热更新机制,可以在保持组件状态的情况下实时预览代码更改。
工作原理#
// Next.js 15.x'use client'
import { useState } from 'react'
export default function Counter() { const [count, setCount] = useState(0)
return ( <div> <p>计数: {count}</p> <button onClick={() => setCount(count + 1)}>+1</button> </div> )}修改这个组件时:
- ✅ 修改 JSX 结构 → 状态保持,UI 更新
- ✅ 修改样式 → 状态保持,样式更新
- ❌ 修改 hooks 逻辑 → 状态重置
保持状态的技巧#
// 使用 key 强制重新挂载;<Counter key={Date.now()} />
// 使用 useEffect 依赖追踪变化useEffect(() => { console.log('组件已更新')}, [])Fast Refresh 失效的情况#
🔶 以下情况会导致完全刷新:
- 组件导出的不是 React 组件
- 文件同时导出组件和非组件
- 使用 Class 组件
- 错误的模块边界
// ❌ 这会导致 Fast Refresh 失效export default function Component() { ... }export const config = { ... } // 非组件导出
// ✅ 拆分到不同文件// component.tsxexport default function Component() { ... }
// config.tsexport const config = { ... }错误处理与调试#
错误叠加层#
开发模式下,Next.js 提供详细的错误信息叠加层:
// 故意引入错误export default function Page() { const user = null return <p>{user.name}</p> // TypeError!}错误叠加层显示:
- 错误类型和消息
- 源代码位置(带行号)
- 调用堆栈
- 一键复制错误信息
console 调试#
Server Component 的 console 输出在终端,Client Component 的在浏览器:
// Server Component - 终端输出export default async function Page() { console.log('服务端日志') // 👈 终端 const data = await fetch('...') return <div>{data}</div>}// Client Component - 浏览器输出'use client'
export default function Button() { console.log('客户端日志') // 👈 浏览器控制台
return <button onClick={() => console.log('点击')}>按钮</button>}断点调试#
VS Code 配置#
{ "version": "0.2.0", "configurations": [ { "name": "Next.js: debug server-side", "type": "node", "request": "attach", "port": 9229, "restart": true, "skipFiles": ["<node_internals>/**"] }, { "name": "Next.js: debug client-side", "type": "chrome", "request": "launch", "url": "http://localhost:3000" } ]}启动调试:
# 开启 Node.js 调试端口NODE_OPTIONS='--inspect' pnpm dev浏览器调试#
- 打开 Chrome DevTools (F12)
- Sources 面板找到
webpack://_N_E/或turbopack:// - 设置断点
React DevTools#
安装 React Developer Tools 浏览器扩展。
🎯 功能:
- 组件树查看
- Props 和 State 检查
- 性能分析
- 组件高亮
// 添加 displayName 便于调试const MyComponent = () => <div>内容</div>MyComponent.displayName = 'MyComponent'
// 或使用具名函数export default function MyComponent() { return <div>内容</div>}性能监控#
内置性能指标#
// Next.js 15.ximport { SpeedInsights } from '@vercel/speed-insights/next'
export default function RootLayout({ children,}: { children: React.ReactNode}) { return ( <html> <body> {children} <SpeedInsights /> </body> </html> )}自定义性能追踪#
// Next.js 15.ximport { unstable_noStore as noStore } from 'next/cache'
export default async function Page() { noStore() // 禁用缓存以测试真实性能
const start = performance.now() const data = await fetch('https://api.example.com/slow-endpoint') const duration = performance.now() - start
console.log(`API 请求耗时: ${duration}ms`)
return <div>...</div>}Bundle 分析#
# 安装分析工具pnpm add -D @next/bundle-analyzer// Next.js 15.ximport type { NextConfig } from 'next'import bundleAnalyzer from '@next/bundle-analyzer'
const withBundleAnalyzer = bundleAnalyzer({ enabled: process.env.ANALYZE === 'true',})
const nextConfig: NextConfig = { // 配置项}
export default withBundleAnalyzer(nextConfig)# 运行分析ANALYZE=true pnpm build生成可视化报告,显示每个模块的体积占比。
常用开发技巧#
1. 快速重启#
# 清除 .next 缓存后重启rm -rf .next && pnpm dev2. 环境变量热更新#
# .env.local 修改后需要重启# 使用 dotenv-cli 可以避免pnpm add -D dotenv-cli{ "scripts": { "dev": "dotenv -e .env.local -- next dev" }}3. 模拟慢网络#
// 开发环境模拟延迟async function getData() { if (process.env.NODE_ENV === 'development') { await new Promise((r) => setTimeout(r, 2000)) // 2秒延迟 } return fetch('...')}4. 条件日志#
export const log = (...args: unknown[]) => { if (process.env.NODE_ENV === 'development') { console.log('[DEV]', ...args) }}
// 使用import { log } from '@/lib/logger'log('调试信息', { data })常见问题#
🤔 Q: Turbopack 报错怎么办?
Turbopack 仍在快速迭代,某些 Webpack 配置可能不兼容。临时方案是回退到 Webpack:
pnpm dev --webpack然后检查 Turbopack 兼容性文档 寻找替代方案。
🤔 Q: Fast Refresh 不生效?
检查组件是否:
- 导出了非组件内容
- 使用了 Class 组件
- 有语法错误
🤔 Q: 如何调试生产构建?
# 生产模式构建pnpm build
# 启动生产服务器pnpm start
# 使用 source map(需配置)下一篇将深入 TypeScript 配置,包括路径别名、严格模式和类型增强。
-EOF-