Next.js 目录结构(实战指南)

Next.js 目录结构解析

Next.js 是一个基于 React 的服务端渲染(SSR)和静态生成(SSG)框架,它的目录结构设计对项目的可维护性和功能组织起着关键作用。了解并掌握 Next.js 的目录结构,是构建高质量应用的基础。

核心概念

Next.js 的目录结构遵循约定优于配置的原则,大多数功能通过文件位置和命名自动推导出路由和行为。例如,pages/ 目录下的每个 .js 文件会自动映射为对应的路由路径。

  • pages/:存放页面组件,支持动态路由、嵌套路由等
  • public/:静态资源目录,如图片、字体、文件等
  • styles/:CSS 或 CSS-in-JS 样式文件
  • components/:可复用的 React 组件
  • utils/:工具函数或业务逻辑辅助模块
  • api/:Next.js API 路由,用于后端逻辑
  • next.config.js:Next.js 的配置文件
  • tsconfig.json / next-env.d.ts:TypeScript 配置相关文件
  • .env:环境变量文件

基础语法

在 Next.js 项目中,pages/ 是目录结构的核心部分。以下是几种常见的用法:

页面路由映射

Next.js 会自动将 pages/ 下的每个文件映射为对应的路由路径。例如:

  • pages/index.js/
  • pages/about.js/about
  • pages/blog/post.js/blog/post

动态路由

Next.js 支持使用 [id].js 的方式创建动态路由:

// pages/blog/[id].js
import { useRouter } from 'next/router'

export default function Post() {
  const router = useRouter()
  const { id } = router.query

  return <div>你正在查看博客 ID: {id}</div>
}

API 路由

Next.js 允许在 pages/api/ 目录下创建 API 接口,每个 .js 文件都会成为一个 API 端点:

// pages/api/hello.js
export default function handler(req, res) {
  res.status(200).json({ name: 'Next.js' })
}

进阶特性

Next.js 的目录结构还支持更多高级特性,如布局组件、异步数据加载、自定义配置等。以下是一些重要用法的表格对比:

特性 说明 示例
布局组件 使用 _app.js_document.js 定义全局布局 pages/_app.js
自定义 404 页面 定义 pages/404.js 处理未找到页面 pages/404.js
自定义文档 使用 _document.js 自定义 HTML 模板 pages/_document.js
API 路由 pages/api/ 目录下创建后端接口 pages/api/data.js
动态导入 使用 next/dynamic 实现按需加载组件 const DynamicComponent = dynamic(() => import('../components/MyComponent'))
自定义配置 next.config.js 中设置构建配置 module.exports = { ... }

实战应用

在真实项目中,一个典型的 Next.js 目录结构可能如下:

my-next-app/
├── pages/
│   ├── index.js         // 首页
│   ├── about.js         // 关于页面
│   ├── blog/
│   │   ├── [id].js      // 博客详情页,支持动态路由
│   │   └── index.js     // 博客列表页
│   └── api/
│       └── fetch-data.js // 获取博客数据的 API
├── components/
│   └── Header.js        // 可复用的头部组件
├── styles/
│   └── global.css       // 全局样式
├── public/
│   └── logo.png         // 静态图片
├── utils/
│   └── helper.js        // 通用工具函数
├── next.config.js       // Next.js 构建配置
└── package.json         // 项目依赖配置

全局布局组件

pages/_app.js 中定义全局布局,所有页面都会继承这个布局:

// pages/_app.js
import '../styles/global.css'
import Header from '../components/Header'

function MyApp({ Component, pageProps }) {
  return (
    <>
      <Header />
      <Component {...pageProps} />
    </>
  )
}

export default MyApp

动态博客详情页

使用动态路由实现博客详情页:

// pages/blog/[id].js
import { useRouter } from 'next/router'

export default function BlogPost() {
  const router = useRouter()
  const { id } = router.query

  return <div>博客详情页 ID: {id}</div>
}

自定义 API 接口

pages/api/ 下创建一个获取数据的接口:

// pages/api/data.js
export default function handler(req, res) {
  const data = {
    title: 'Next.js 目录结构',
    description: 'Next.js 项目中各目录的作用和使用场景'
  }
  res.status(200).json(data)
}

注意事项

  1. 页面组件必须导出默认函数组件
    每个页面文件(如 pages/index.js)必须导出一个默认函数组件,否则 Next.js 无法识别。

  2. 动态路由文件名格式必须正确
    动态路由文件名需要使用 [参数名].js 的格式,例如 [id].js,否则无法正确解析路由参数。

  3. 避免在 pages/ 目录下使用嵌套过深的结构
    虽然 Next.js 支持嵌套路由,但过深的嵌套会增加维护难度,建议保持页面结构扁平。

  4. public/ 目录下的文件不会被 Webpack 处理
    静态资源应放在 public/ 目录下,如图片、字体等,这些文件不会经过代码打包处理,可直接通过 /public/文件名 访问。

总结

Next.js 的目录结构直接影响项目路由和构建行为,掌握其组织方式能让你更高效地开发和维护应用。