Next.js 入门:核心概念介绍 – wiki基地


迈向现代前端新纪元:Next.js 入门——核心概念深入解析

在当今快速迭代的 Web 开发领域,构建高性能、用户体验优秀且易于维护的现代 Web 应用是每个开发者追求的目标。React 作为构建用户界面的强大库,极大地提高了开发效率。然而,纯粹的客户端渲染(Client-Side Rendering, CSR)模式在某些场景下(如搜索引擎优化 SEO、首屏加载速度、代码分割等)存在局限性。

这时,Next.js 应运而生。它是一个基于 React 的、生产级别的全栈 Web 应用框架,由 Vercel 公司开发和维护。Next.js 在 React 的基础上,提供了诸多开箱即用的功能和优化,极大地简化了构建现代 Web 应用的复杂性,让开发者能够更专注于业务逻辑而非繁琐的配置。

如果你已经有 React 的基础,并希望构建更强大、更优化的 Web 应用,那么学习 Next.js 将是你的下一个重要里程碑。本文将带你深入探索 Next.js 的核心概念,为你打开现代全栈 React 开发的大门。

为什么选择 Next.js?它解决了什么问题?

在深入 Next.js 的具体功能之前,我们先来理解一下为什么 Next.js 如此受欢迎,以及它主要解决了 React 客户端应用开发中的哪些痛点。

传统的客户端渲染(CSR)模式,例如使用 Create React App (CRA) 构建的应用,通常工作流程是:
1. 浏览器请求页面。
2. 服务器返回一个包含少量 HTML 和 <script> 标签的空壳文件。
3. 浏览器下载 JavaScript 文件。
4. 浏览器执行 JavaScript,React 应用开始运行,动态渲染页面内容。

这种模式对于单页应用(SPA)来说,提供了流畅的用户体验,但在以下方面存在挑战:

  1. 搜索引擎优化 (SEO): 搜索引擎爬虫在抓取页面时,可能无法完整执行 JavaScript 并获取动态加载的内容,导致页面的真实内容无法被索引,影响 SEO。
  2. 首屏加载速度: 用户需要等待 JavaScript 下载和执行完成后才能看到完整的页面内容,这会导致白屏时间较长,影响用户体验,尤其是在网络条件不佳的情况下。
  3. 性能优化: 复杂的代码分割、资源预加载等需要手动配置或依赖额外的库,增加了开发和维护的复杂度。
  4. 服务器端渲染 (SSR) 配置: 如果需要实现服务器端渲染来解决 SEO 和首屏加载问题,传统的 React 应用需要进行复杂的配置,包括服务器设置、路由同步、数据同构等,门槛较高。
  5. 全栈能力: React 本身只是一个 UI 库,如果需要构建后端 API,通常需要单独的技术栈(如 Node.js + Express, Python + Django/Flask 等),增加了项目复杂性。

Next.js 恰恰是为解决这些问题而设计的。它提供了一套集成的解决方案,让你能够轻松构建具备以下特性的应用:

  • 内置服务器端渲染 (SSR) 和静态站点生成 (SSG): Next.js 支持多种渲染策略,可以根据页面特性选择最佳方案,从而改善 SEO 和首屏性能。
  • 基于文件系统的路由: 无需手动配置路由,只需在特定目录下创建文件即可自动生成路由。
  • 自动代码分割: Next.js 会根据页面自动进行代码分割,只加载当前页面所需的代码,提高加载速度。
  • API Routes: 允许你在 Next.js 项目中创建 Node.js 后端 API,实现真正的全栈开发。
  • 开箱即用的功能: 包括样式支持(CSS Modules, CSS-in-JS, Sass)、图片优化、环境变量、Fast Refresh 等,提升开发效率和体验。
  • 简单易用的部署: 与 Vercel 等平台深度集成,部署流程非常简单。

总而言之,Next.js 为 React 开发者提供了一个强大而高效的框架,它抽象了许多复杂的底层配置,让开发者能够更专注于构建优秀的 Web 应用。

入门第一步:创建你的第一个 Next.js 应用

开始 Next.js 之旅最简单的方式就是使用官方提供的 create-next-app 工具,类似于 React 的 CRA。

确保你安装了 Node.js (推荐 LTS 版本) 和 npm 或 yarn 或 pnpm。

打开终端,运行以下命令:

“`bash
npx create-next-app@latest my-next-app

或者使用 yarn

yarn create next-app my-next-app

或者使用 pnpm

pnpm create next-app my-next-app

“`

运行命令后,它会询问你一些配置问题,例如:

  • 项目名称 (my-next-app)
  • 是否使用 TypeScript (推荐选择 Yes)
  • 是否使用 ESLint (推荐选择 Yes)
  • 是否使用 Tailwind CSS (根据喜好选择)
  • 是否使用 src 目录 (推荐选择 Yes)
  • 是否使用 App Router (推荐选择 Yes,这是 Next.js 13+ 的新标准,尽管本文也会介绍 Pages Router 的核心概念,但 App Router 是未来)
  • 是否自定义 import alias (e.g. @/*) (推荐选择 Yes)

选择完成后,工具会自动创建项目并安装依赖。

进入项目目录:

bash
cd my-next-app

运行开发服务器:

“`bash
npm run dev

或者 yarn dev

或者 pnpm dev

“`

现在,打开浏览器访问 http://localhost:3000,你就能看到 Next.js 的默认欢迎页面了!

项目结构概览 (App Router 为主,附带 Pages Router 介绍)

create-next-app 创建的项目结构简洁明了。对于 Next.js 13+ 且选择了 App Router 的项目,核心目录通常是 apppublic

my-next-app/
├── app/ # App Router 目录
│ ├── layout.tsx # 根布局文件
│ ├── page.tsx # 根页面文件 (对应 '/')
│ └── globals.css # 全局 CSS
├── public/ # 静态资源目录
│ └── favicon.ico # 网站图标
├── src/ # 如果你选择了 src 目录
│ ├── app/ # App Router 目录 (同上)
│ └── components/ # 存放可复用 React 组件
├── next.config.js # Next.js 配置文件
├── package.json # 项目依赖和脚本
├── README.md # 项目说明
└── tsconfig.json # TypeScript 配置文件 (如果选择了 TypeScript)

核心目录和文件说明:

  • app/ (App Router): 这是 Next.js 13+ 引入的新的路由和渲染范式。它基于文件系统,目录结构直接映射到 URL 路径。

    • page.tsx: 对应一个路由段的 UI 界面。例如 app/page.tsx 对应根路由 /app/about/page.tsx 对应 /about
    • layout.tsx: 对应一个路由段的布局。布局会包裹其下的 page 文件,可以用来定义共享的 UI 结构(如导航栏、侧边栏)。app/layout.tsx 是应用的根布局。
    • template.tsx: 类似于 layout,但每次导航时都会重新创建组件实例,用于一些需要状态重置或入口/出口动画的场景。
    • loading.tsx: 在加载同一路由段下的内容时显示的 loading UI。
    • error.tsx: 处理同一路由段及其子段中的错误。
    • not-found.tsx: 处理同一路由段及其子段下的 404 错误。
    • default.tsx: 作为 parallel routes 的 fallback。
    • route.ts: 对应 API 路由(新的 App Router API 路由)。
    • [folderName]: 定义动态路由参数,例如 app/products/[id]/page.tsx
  • public/: 这个目录用于存放静态资源,如图片、字体、Favicon 等。放在这里的资源可以直接通过根路径访问,例如 public/favicon.ico 可以通过 /favicon.ico 访问。

  • src/: 如果你选择了这个选项,你的应用代码会放在 src/appsrc/components 等目录下,这是一种常见的代码组织方式。

  • next.config.js: Next.js 的配置文件,你可以在这里配置各种构建选项、环境变量、重定向、图片优化策略等。

Pages Router (传统方式,Next.js 13- 或选择不使用 App Router 时):

如果你没有选择 App Router,或者你的项目是基于 Next.js 12 或更早版本,核心目录是 pages

my-next-app/
├── pages/ # Pages Router 目录
│ ├── index.tsx # 对应 '/' 路径
│ ├── about.tsx # 对应 '/about' 路径
│ ├── _app.tsx # 自定义 App 组件 (用于初始化页面,如添加全局样式、Providers)
│ ├── _document.tsx # 自定义 Document 组件 (用于修改 HTML 结构,如添加 meta 标签、引入外部脚本)
│ └── api/ # API Routes 目录
│ └── hello.ts # 对应 '/api/hello' 路径
├── public/ # 静态资源目录 (同上)
├── components/ # 存放可复用 React 组件
├── next.config.js # Next.js 配置文件
├── package.json # 项目依赖和脚本
└── tsconfig.json # TypeScript 配置文件

  • pages/ (Pages Router): 这个目录下的文件直接映射到 URL 路径。
    • pages/index.tsx: 对应应用的根路由 /
    • pages/about.tsx: 对应 /about 路由。
    • pages/posts/[slug].tsx: 对应动态路由,如 /posts/first-post, /posts/another-post[slug] 是动态参数。
    • pages/api/: 这个目录用于创建 API 路由。pages/api/hello.ts 对应 /api/hello 接口。
    • pages/_app.tsx: 用于自定义应用的初始化,例如在所有页面加载前应用全局 CSS,或者注入 Context Providers。
    • pages/_document.tsx: 用于自定义应用的 HTML 文档结构(<html>, <body> 等),例如添加自定义字体、meta 标签等。

注意: App Router 是 Next.js 的最新推荐路由方式,它带来了服务器组件、嵌套路由、并行路由等强大功能,是 Next.js 的发展方向。虽然 Pages Router 仍然可用且被广泛使用,但新项目建议优先考虑 App Router。本文后续内容会结合介绍 App Router 的概念,但也会触及 Pages Router 中对应的概念,以便理解 Next.js 的演进和兼容性。

核心概念一:基于文件系统的路由

无论是 App Router 还是 Pages Router,Next.js 最直观的核心概念之一就是其基于文件系统的路由。你无需安装和配置像 React Router 这样的库,Next.js 会根据 apppages 目录下的文件结构自动生成应用的路由。

App Router 中的路由:

  • 约定: app 目录下的文件夹代表 URL 的一个段,而该文件夹内的 page.tsx 文件则定义了该路由段的 UI。
  • 示例:
    • app/page.tsx -> /
    • app/about/page.tsx -> /about
    • app/dashboard/settings/page.tsx -> /dashboard/settings
  • 嵌套路由和布局: 通过创建嵌套文件夹,可以创建嵌套路由。例如 app/dashboard/page.tsxapp/dashboard/settings/page.tsx。你可以在 app/dashboard/layout.tsx 中定义一个布局,它将应用于 /dashboard/dashboard/settings 及其子路由。
  • 动态路由: 使用方括号 [] 定义动态路由参数。例如 app/products/[id]/page.tsx 会匹配 /products/1, /products/abc 等路径,id 参数可以在页面组件中获取。

Pages Router 中的路由:

  • 约定: pages 目录下的文件直接映射到 URL。文件名为 index.jsindex.tsx 对应目录的根路径。
  • 示例:
    • pages/index.tsx -> /
    • pages/about.tsx -> /about
    • pages/posts/index.tsx -> /posts
    • pages/dashboard/settings.tsx -> /dashboard/settings
  • 动态路由: 使用方括号 [] 定义动态文件或目录名。例如 pages/posts/[slug].tsx 会匹配 /posts/hello-world 等路径,slug 参数可以在页面组件中获取。pages/[user]/settings.tsx 会匹配 /john/settings, /jane/settings 等。
  • API 路由: 任何放在 pages/api 目录下的文件都会被视为 API 路由,而不是页面。例如 pages/api/user.ts 对应 /api/user

导航:

Next.js 提供了 <Link> 组件 (next/link) 用于在应用内部进行客户端路由跳转。使用 <Link> 组件可以实现单页应用的平滑导航,而无需触发浏览器刷新。

“`jsx
// App Router 或 Pages Router 中都适用
import Link from ‘next/link’;

function Navigation() {
return (

);
}
“`

相比于传统的 <a> 标签,<Link> 组件会自动进行预加载(Prefetching),即在链接进入用户视口时,Next.js 会在后台预加载目标页面所需的资源,从而在用户点击时实现即时导航。

核心概念二:渲染策略 (SSG, SSR, CSR, ISR)

这是 Next.js 最强大也是最核心的特性之一。Next.js 提供了多种渲染策略,允许你根据页面内容的特性选择最优的方式,以平衡性能、SEO 和数据实时性。

1. 静态站点生成 (Static Site Generation, SSG)

  • 工作原理: 在项目构建时 (build time),Next.js 会预先渲染页面,生成静态的 HTML 文件以及相关的 CSS 和 JavaScript。这些静态文件可以直接部署到 CDN 上。
  • 优点:
    • 极快的访问速度: 用户请求时直接获取预生成的 HTML,无需服务器端实时计算。
    • 优秀的 SEO: 搜索引擎爬虫可以直接抓取完整的 HTML 内容。
    • 低成本部署: 静态文件托管成本非常低廉。
  • 适用场景: 内容不经常变化或变化不要求实时性高的页面,如博客文章、营销落地页、文档网站、产品列表页等。
  • App Router 实现 (推荐): 默认情况下,app 目录下的组件是 React Server Components,它们在服务器上渲染为静态 HTML。数据获取通常在 Server Component 中使用 fetch 或其他库完成,并自动缓存。
  • Pages Router 实现: 在页面组件中导出 getStaticProps 函数。这个函数在构建时运行,用于获取页面所需的 props。

    “`javascript
    // pages/posts/[slug].js (Pages Router example)
    import { getStaticProps, getStaticPaths } from ‘next’;

    // 这会在构建时运行,为每个 slug 获取数据
    export const getStaticProps = async ({ params }) => {
    const postData = await getPostBySlug(params.slug); // 模拟数据获取
    return {
    props: {
    postData,
    },
    // revalidate: 60, // 启用 ISR,可选
    };
    };

    // 这会在构建时运行,定义需要预渲染的动态路径
    export const getStaticPaths = async () => {
    const paths = await getAllPostSlugs(); // 模拟获取所有 slug
    return {
    paths, // [{ params: { slug: ‘post-a’ } }, { params: { slug: ‘post-b’ } }]
    fallback: ‘blocking’, // 或者 true / false
    };
    };

    // 页面组件接收 getStaticProps 返回的 props
    function Post({ postData }) {
    return (

    {postData.title}

    {postData.content}

    );
    }

    export default Post;
    ``
    *
    getStaticProps: 负责获取数据。
    *
    getStaticPaths: 如果是动态路由 ([slug].js),需要配合getStaticPaths来告诉 Next.js 在构建时需要生成哪些具体路径的页面(例如/posts/hello-world,/posts/another-post)。fallback选项决定了当用户请求一个构建时未生成的路径时 Next.js 的行为 (false-> 404;true-> 客户端渲染并生成新静态文件;‘blocking’` -> 服务器端渲染并缓存)。

2. 服务器端渲染 (Server-Side Rendering, SSR)

  • 工作原理: 在用户每次请求页面时,Next.js 服务器都会实时执行 React 代码,将页面渲染成 HTML,然后将 HTML 发送给浏览器。客户端接收到 HTML 后,JavaScript 会在后台加载并“激活”页面,使其具备交互能力(hydration)。
  • 优点:
    • 优秀的 SEO: 搜索引擎爬虫可以获取完整的 HTML 内容。
    • 较好的首屏加载速度: 用户可以快速看到页面内容,即使内容是动态生成的。
    • 数据实时性高: 每次请求都会获取最新数据。
  • 适用场景: 内容频繁变化、需要实时数据的页面,或需要根据用户身份显示不同内容的页面,如电商商品详情页、新闻详情页、用户仪表盘等。
  • App Router 实现 (推荐): 默认情况下,app 目录下的 Server Components 也是支持 SSR 的。如果数据是动态的且不应该被缓存(例如依赖 Cookie 或 Header),可以使用 fetch API 并设置 cache: 'no-store',或者使用 Router Handler (新的 API 路由)。
  • Pages Router 实现: 在页面组件中导出 getServerSideProps 函数。这个函数在每次用户请求页面时都会在服务器端运行。

    “`javascript
    // pages/user/[id].js (Pages Router example)
    import { getServerSideProps } from ‘next’;

    // 这会在每次请求时运行,为当前请求获取数据
    export const getServerSideProps = async ({ params, req, res }) => {
    const userData = await fetchUserData(params.id, req.headers.cookie); // 模拟数据获取,可访问请求信息
    if (!userData) {
    return {
    notFound: true, // 返回 404 页面
    };
    }
    return {
    props: {
    userData,
    },
    };
    };

    // 页面组件接收 getServerSideProps 返回的 props
    function UserProfile({ userData }) {
    return (

    {userData.name}

    {userData.email}

    );
    }

    export default UserProfile;
    ``
    *
    getServerSideProps: 负责在每次请求时获取数据。它可以访问请求相关的上下文信息(如req,res`)。

3. 客户端渲染 (Client-Side Rendering, CSR)

  • 工作原理: 这是传统的 React SPA 模式。服务器返回最小的 HTML 文件,数据获取和页面渲染完全在浏览器端通过 JavaScript 执行。
  • 优点:
    • 适合强交互应用: 用户体验流畅,页面切换快,适合仪表盘、复杂的表单等。
  • 缺点:
    • SEO 不友好( unless you use dynamic rendering like Prerender.io or have a robust client-side SEO strategy).
    • 首屏加载可能较慢。
  • 适用场景: 用户登录后的仪表盘、高度依赖用户交互的内部工具等对 SEO 和首屏不敏感的页面。
  • App Router 实现: 在组件文件的顶部添加 'use client' 指令。这会将该组件及其所有子组件标记为 Client Components。数据获取可以在 Client Component 中使用 React 的 Effect Hook (useEffect) 或 SWR, React Query 等库进行。
  • Pages Router 实现: 这是 Pages Router 页面的默认行为。在页面组件中使用 useEffect 等 React Hook 进行数据获取。

    “`javascript
    // pages/dashboard.js (Pages Router example)
    import { useState, useEffect } from ‘react’;

    function Dashboard() {
    const [data, setData] = useState(null);

    useEffect(() => {
    // 在客户端加载后执行数据获取
    fetch(‘/api/dashboard-data’)
    .then(res => res.json())
    .then(setData);
    }, []); // 仅在组件挂载时执行一次

    if (!data) {
    return

    Loading dashboard…

    ;
    }

    return (

    Dashboard

    Data: {JSON.stringify(data)}

    );
    }

    export default Dashboard;
    “`

4. 增量静态再生 (Incremental Static Regeneration, ISR)

  • 工作原理: 这是 SSG 的一个增强。你可以在 getStaticProps 中指定一个 revalidate 参数(秒数)。Next.js 会在构建时生成页面的静态版本。当用户请求页面时,如果距离上次生成超过 revalidate 秒,Next.js 会返回旧的(缓存的)静态页面,同时在后台重新生成新的静态页面来替换旧的缓存。随后的请求就会获取到新的页面。
  • 优点: 结合了 SSG 的性能优势和 SSR 的数据更新能力,无需完全重建整个站点即可更新静态内容。
  • 适用场景: 内容更新频率较高但不需要极致实时的页面,如电商网站首页推荐商品、博客文章列表(当新文章发布时可以后台更新)。
  • Pages Router 实现:getStaticProps 的返回值中添加 revalidate: number
  • App Router 实现: 在 Server Component 中使用 fetch 获取数据时,可以配置缓存行为。默认情况下 fetch 会自动缓存请求结果,并可以使用 next: { revalidate: number } 来指定缓存过期时间,实现类似 ISR 的效果。

总结渲染策略:

选择哪种策略取决于页面内容的特性:

  • SSG (或 App Router 中的默认 Server Components): 最佳性能和 SEO,适用于静态或不常更新的内容。
  • SSR (或 App Router 中的动态 Server Components/Route Handlers): 适用于需要实时数据或用户特定内容的页面,兼顾性能和 SEO。
  • CSR (或 App Router 中的 Client Components): 适用于强交互、对 SEO 和首屏不敏感的页面。
  • ISR: SSG 的优化,适用于需要定时更新静态内容的场景。

Next.js 的强大之处在于,你可以在同一个应用中为不同的页面选择不同的渲染策略。

核心概念三:数据获取

数据获取是 Web 应用不可或缺的一部分。Next.js 提供了一套与渲染策略紧密结合的数据获取方式。

Pages Router 中的数据获取函数:

  • getStaticProps: (用于 SSG) 在构建时在服务器端运行。无法访问请求相关信息。返回 props 会传递给页面组件。
  • getStaticPaths: (用于 SSG 动态路由) 在构建时在服务器端运行。定义需要预渲染的动态路径。
  • getServerSideProps: (用于 SSR) 在每次请求时在服务器端运行。可以访问请求相关信息。返回 props 会传递给页面组件。
  • 客户端数据获取: 在页面组件或组件内部使用 useEffect 配合 fetch 或 SWR/React Query 等库进行。

App Router 中的数据获取 (推荐):

App Router 引入了 React Server Components 的概念,改变了数据获取的方式。

  • Server Components (默认): 大部分组件默认是 Server Components,它们在服务器上渲染。数据获取可以直接在 Server Components 中进行,无需 Hooks。
    • 可以使用原生的 fetch API,Next.js 会自动对其进行扩展,提供缓存、去重等功能。
    • 可以安装并使用任何支持 Node.js 环境的数据获取库(如 axios, ORMs 等)。
    • 默认情况下,fetch 请求会被缓存,可以使用 cache: 'no-store' 禁用缓存实现 SSR 行为,或者使用 next: { revalidate: number } 实现 ISR 行为。
  • Client Components ('use client'): 需要客户端交互的组件被标记为 Client Components。数据获取通常在 useEffect 或事件处理器中进行,或者使用 SWR/React Query 等客户端数据获取库。

示例 (App Router):

“`jsx
// app/products/[id]/page.tsx (这是一个 Server Component)

// 可以在 Server Component 中直接定义 async 函数获取数据
async function getProduct(id: string) {
const res = await fetch(https://.../products/${id});
// 默认情况下,fetch 会缓存数据。如需 SSR 行为,使用 cache: ‘no-store’
// const res = await fetch(https://.../products/${id}, { cache: ‘no-store’ });
// 如需 ISR 行为,使用 revalidate
// const res = await fetch(https://.../products/${id}, { next: { revalidate: 60 } });

if (!res.ok) {
// 建议根据状态码处理错误
throw new Error(‘Failed to fetch product’);
}
return res.json();
}

// page 组件现在可以直接是一个 async 函数
export default async function ProductPage({ params }: { params: { id: string } }) {
const product = await getProduct(params.id);

return (

{product.name}

{product.description}

Price: ${product.price}

);
}
“`

这种方式使得数据获取代码更接近于组件,提高了代码的可读性和组织性。Server Components 可以在服务器上直接访问数据库或后端服务,无需通过 API 层(尽管 API Routes 仍然有用)。

核心概念四:API Routes (App Router 中的 Route Handlers)

Next.js 允许你在同一个项目中创建前后端代码。API Routes (在 App Router 中称为 Route Handlers) 提供了一种简单的方式来构建你自己的 API 接口,而无需单独搭建一个后端服务器。

Pages Router 中的 API Routes:

  • 文件放在 pages/api 目录下。
  • 每个文件导出一个默认的异步函数,该函数接收 req (request) 和 res (response) 对象,类似于 Node.js 的 Express 或 Koa 中间件。
  • 文件名决定了 API 的路径。
  • 示例 (pages/api/hello.ts):

    “`typescript
    import type { NextApiRequest, NextApiResponse } from ‘next’;

    type Data = {
    name: string;
    };

    export default function handler(
    req: NextApiRequest,
    res: NextApiResponse
    ) {
    res.status(200).json({ name: ‘John Doe’ });
    }
    ``
    这个 API 可以通过
    /api/hello` 访问。

App Router 中的 Route Handlers:

  • 文件放在 app 目录下的 route.tsroute.js 文件中。
  • 与页面文件 (page.tsx) 不同,route.ts 不返回 React 组件,而是处理 HTTP 请求。
  • 你可以在 route.ts 文件中导出不同的 HTTP 方法的处理函数(GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS)。
  • 示例 (app/api/users/route.ts):

    “`typescript
    // 这是 App Router 中的 API 路由,称为 Route Handler
    import { NextResponse } from ‘next/server’;

    export async function GET() {
    // 模拟从数据库获取数据
    const users = [
    { id: 1, name: ‘Alice’ },
    { id: 2, name: ‘Bob’ },
    ];

    return NextResponse.json(users);
    }

    export async function POST(request: Request) {
    const data = await request.json();
    // 模拟向数据库添加用户
    console.log(‘Received user data:’, data);

    return NextResponse.json({ message: ‘User created’, user: data }, { status: 201 });
    }
    ``
    这个 API 可以通过
    /api/users` 访问,支持 GET 和 POST 请求。

API Routes 或 Route Handlers 非常适合用于:

  • 构建供客户端或 Server Components 调用的后端 API。
  • 处理表单提交。
  • 与数据库或外部服务交互。
  • 实现身份验证逻辑。

核心概念五:样式处理

Next.js 对样式提供了很好的支持,你可以选择多种方式:

  1. CSS Modules (推荐):

    • 创建以 .module.css 结尾的文件(例如 styles/Home.module.css)。
    • 导入样式时,样式类名会被自动哈希化,实现局部作用域,避免样式冲突。
    • 示例:
      css
      /* styles/Button.module.css */
      .button {
      padding: 10px 20px;
      background-color: blue;
      color: white;
      }

      “`jsx
      // components/MyButton.tsx
      import styles from ‘../styles/Button.module.css’;

      function MyButton() {
      return ;
      }
      “`

  2. 全局 CSS:

    • app 目录下的 globals.css (App Router) 或 pages/_app.tsx (Pages Router) 中导入全局 CSS 文件。
    • 全局 CSS 会影响整个应用。通常用于重置样式、定义全局变量或引入第三方 CSS 库。
    • 注意: 在 Pages Router 中,全局 CSS 只能_app.tsx 中导入。
  3. Styled JSX (内置):

    • Next.js 内置支持 Styled JSX,一种 CSS-in-JS 库,允许你在组件内部使用 jsx 属性编写带作用域的 CSS。
    • 示例:
      jsx
      function MyComponent() {
      return (
      <div>
      <p>Hello, Styled JSX!</p>
      <style jsx>{`
      p {
      color: purple;
      font-size: 18px;
      }
      `}</style>
      </div>
      );
      }
  4. 预处理器 (Sass):

    • 安装 sass 包,然后可以直接导入 .scss.sass 文件。Next.js 会自动编译。
  5. 第三方 CSS-in-JS 库:

    • 你可以集成像 Styled Components, Emotion 等流行的 CSS-in-JS 库。通常需要在 pages/_app.tsx 或 App Router 的根布局中进行一些初步设置。

对于大多数情况,CSS Modules 是一个很好的起点,它提供了模块化和避免冲突的优势。

核心概念六:图片优化 (next/image)

图片是网页性能的重要杀手。Next.js 提供了一个 <Image> 组件 (next/image),它会自动为你优化图片,包括:

  • 延迟加载 (Lazy Loading): 图片只在进入视口时加载。
  • 响应式图片: 根据用户设备和屏幕尺寸自动加载不同尺寸的图片,节省带宽。
  • 图片格式优化: 支持现代图片格式(如 WebP),并自动转换。
  • 图片大小优化: 在服务器端按需调整图片尺寸。
  • 防止布局偏移 (Layout Shift): 自动处理图片尺寸,减少 CLS (Cumulative Layout Shift)。

使用 <Image> 组件代替原生的 <img> 标签是提升性能的关键优化之一。

示例:

“`jsx
import Image from ‘next/image’;
import profilePic from ‘../public/profile.jpg’; // 支持导入本地图片

function Profile() {
return (
Picture of the author
);
}
“`

其他重要概念

  • Fast Refresh: Next.js 内置的快速刷新功能,可以在编辑 React 组件时即时看到更改,保持组件状态,极大地提升开发效率。
  • 环境变量: Next.js 支持 .env.local 等文件来配置环境变量,这些变量可以在服务器端和客户端访问(以 NEXT_PUBLIC_ 开头)。
  • Middleware (中间件): 允许你在请求完成之前运行代码,例如重定向、修改请求/响应头、身份验证等。可以在项目根目录下创建 middleware.ts 文件。
  • TypeScript 支持: Next.js 对 TypeScript 提供了优秀的内置支持,提供了更好的开发体验和代码健壮性。

部署 Next.js 应用

部署 Next.js 应用非常简单,尤其是使用 Vercel (Next.js 的创建者公司提供的平台)。

  • Vercel: 将你的 Next.js 项目连接到 Vercel 仓库,Vercel 会自动检测是 Next.js 项目并进行优化部署,包括构建、托管静态文件、配置 serverless functions (用于 SSR 和 API Routes/Route Handlers)。每次 Git Push 都会触发自动部署。
  • Static Export: 你可以使用 next export 命令将 Next.js 应用导出为完全静态的 HTML、CSS 和 JS 文件。这种方式只能用于那些完全使用 SSG 的页面,不能包含 SSR 或 API Routes。导出后可以部署到任何静态文件托管服务。
  • Node.js Server: 你也可以构建 Next.js 应用 (next build),然后使用 next start 命令在自己的 Node.js 服务器上运行。

总结与下一步

通过本文的介绍,你应该对 Next.js 的核心概念有了初步的理解:

  • 它是一个基于 React 的全栈框架,解决了传统客户端渲染的痛点。
  • 基于文件系统的路由让页面创建变得直观。
  • 灵活的渲染策略 (SSG, SSR, CSR, ISR) 允许你根据需求优化性能和 SEO。
  • 强大的数据获取方式与渲染策略紧密集成。
  • API Routes / Route Handlers 让你可以在同一个项目中构建后端接口。
  • 内置的样式、图片优化等功能提升了开发效率和应用性能。

掌握这些核心概念,你已经迈出了 Next.js 开发的第一步。

下一步建议:

  1. 动手实践: 尝试使用 create-next-app 创建一个新项目,并实践本文中介绍的路由、创建页面、尝试不同的数据获取方式。
  2. 深入 App Router: 详细阅读 Next.js 官方文档关于 App Router 的部分,理解 Server Components, Client Components, Data Fetching in App Router 等新概念。
  3. 学习 Pages Router (作为补充): 如果你需要维护旧项目或想更全面了解 Next.js,也可以学习 Pages Router 的细节,理解 _app, _document, getStaticProps, getServerSideProps 等。
  4. 探索更多功能: 学习 Next.js 的更多高级功能,如 Middleware, Authentication, Deploying Strategies, Customizing next.config.js 等。
  5. 构建小型项目: 通过构建一个真实的、小型的 Next.js 项目来巩固知识,例如一个简单的博客、产品展示网站或待办事项应用。

Next.js 社区活跃,文档详尽,是学习和构建现代 Web 应用的绝佳选择。祝你在 Next.js 的世界里探索愉快,构建出色的应用!


发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部