Next.js 快速入门:构建你的第一个应用 – wiki基地


Next.js 快速入门:构建你的第一个应用

欢迎来到 Next.js 的世界!如果你是 React 开发者,并且希望构建功能强大、性能卓越、对搜索引擎友好且开发体验极佳的应用,那么 Next.js 无疑是一个非常棒的选择。它是一个基于 React 的全栈 Web 框架,提供了服务端渲染 (SSR)、静态网站生成 (SSG)、路由、API 路由、代码分割等一系列开箱即用的功能,极大地简化了现代 Web 应用的开发流程。

本文将手把手带你迈出 Next.js 的第一步,从零开始创建一个 Next.js 应用,了解其核心概念,并构建一个简单的页面和组件。

为什么选择 Next.js?

在深入实践之前,我们先快速了解一下 Next.js 的主要优势:

  1. 服务端渲染 (SSR) 和静态网站生成 (SSG):Next.js 支持多种渲染模式,可以根据需要选择 SSR(动态内容)、SSG(静态内容)或客户端渲染 (CSR)。这有助于提高应用性能、改善用户体验,并对 SEO 非常友好。
  2. 文件系统路由:通过创建文件和文件夹来定义应用的路由,直观且易于管理。
  3. API 路由:可以在 Next.js 项目内部轻松创建 API 端点,无需单独的后端服务。
  4. 代码分割和优化:Next.js 会自动进行代码分割,只加载当前页面所需的 JavaScript 代码,提升页面加载速度。同时还内置了图片优化、字体优化等功能。
  5. 优秀开发者体验:提供快速刷新(Fast Refresh)、内置 CSS 支持、TypeScript 支持、ESLint 等,让开发更加高效愉快。
  6. 强大的社区和生态:作为流行的框架,Next.js 拥有庞大的社区支持和丰富的第三方库。

前置准备

在开始之前,请确保你的开发环境中已安装以下工具:

  1. Node.js: 建议安装 LTS (长期支持) 版本。你可以访问 Node.js 官网 下载安装。
  2. npm, yarn 或 pnpm: Node.js 安装后会自带 npm。你也可以选择安装 yarn 或 pnpm 作为包管理器。
  3. 代码编辑器: 如 VS Code, Sublime Text, WebStorm 等。
  4. 基础 React 知识: 虽然 Next.js 帮你处理了很多底层细节,但理解 React 的组件、Props、State、Hooks 等概念是必要的。

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

创建 Next.js 应用最推荐的方式是使用官方提供的 create-next-app 脚手架工具。它会为你设置好一个基础的项目结构和必要的配置。

打开你的终端或命令行工具,运行以下命令:

bash
npx create-next-app@latest

这个命令会使用最新版本的 create-next-app。运行后,它会引导你进行一系列配置选择:

√ What is your project named? ... my-next-app # 项目名称
√ Would you like to use TypeScript? ... Yes/No # 是否使用 TypeScript (强烈推荐使用 TypeScript)
√ Would you like to use ESLint? ... Yes/No # 是否使用 ESLint (推荐使用,用于代码规范检查)
√ Would you like to use Tailwind CSS? ... Yes/No # 是否使用 Tailwind CSS (流行的原子化 CSS 框架,可根据喜好选择)
√ Would you like to use `src/` directory? ... Yes/No # 是否使用 src/ 目录来组织代码 (推荐使用,结构更清晰)
√ Use App Router (recommended)? ... Yes/No # 是否使用 App Router (这是 Next.js 13+ 推出的新路由系统,也是官方推荐的未来方向,我们将基于 App Router 进行讲解)
√ Would you like to customize the default import alias (@/*)? ... Yes/No # 是否自定义导入别名 (默认是 @/*,方便导入 src 目录下的模块)

按照你的偏好进行选择。对于本教程,我们选择:

  • 项目名称: my-next-app
  • TypeScript: Yes
  • ESLint: Yes
  • Tailwind CSS: No (为了简化,我们使用普通的 CSS 或 CSS Modules)
  • src/ directory: Yes
  • App Router: Yes
  • Import alias: No (使用默认的 @/*)

选择完成后,create-next-app 会自动创建项目目录、安装必要的依赖。这个过程可能需要几分钟。

安装完成后,进入项目目录:

bash
cd my-next-app

现在,运行开发服务器:

“`bash
npm run dev

或者 yarn dev

或者 pnpm dev

“`

稍等片刻,终端会显示类似以下信息:

ready - started server on 0.0.0.0:3000, url: http://localhost:3000

打开你的浏览器,访问 http://localhost:3000,你将看到 Next.js 的默认启动页面。恭喜你,你的第一个 Next.js 应用已经成功运行起来了!

第二步:理解项目结构 (App Router)

使用 create-next-app 创建的项目结构可能会根据你的选择略有不同,但核心目录和文件是类似的。由于我们选择了 App Router 并使用了 src/ 目录,你的项目结构大致如下:

my-next-app/
├── node_modules/
├── public/ # 存放静态资源,如图片、字体等,可以直接通过根路径访问
├── src/
│ ├── app/ # App Router 的核心目录
│ │ ├── favicon.ico # 应用图标
│ │ ├── global.css # 全局 CSS 文件
│ │ ├── layout.tsx # 根布局文件,定义 HTML 结构和共享 UI
│ │ └── page.tsx # 应用的根页面 (对应 / 路径)
│ └── app/globals.css # 或者全局样式在 src/globals.css
├── .eslintrc.json # ESLint 配置文件
├── .gitignore # Git 忽略文件
├── next-env.d.ts # Next.js 环境变量的 TypeScript 类型定义
├── next.config.js # Next.js 配置文件
├── package.json # 项目依赖和脚本
├── README.md # 项目说明文件
├── tsconfig.json # TypeScript 配置文件

  • app/ 目录: 这是 App Router 的核心。所有路由、布局、页面、加载状态、错误边界等都在这个目录下定义。
  • page.tsx: 在一个路由段中,page.tsx (或 .js, .jsx) 文件是该路由段的入口文件,它默认导出的是一个 React 组件,渲染该路由的 UI。例如,app/page.tsx 对应 / 路径,app/about/page.tsx 对应 /about 路径。
  • layout.tsx: 在一个路由段中,layout.tsx 文件定义了该路由段及其子路由段的布局。根目录下的 app/layout.tsx 是整个应用的根布局,通常在这里定义 <html>, <body> 标签以及共享的导航、页脚等。
  • global.css: 用于定义全局样式。
  • public/: 存放不需要经过 Webpack 处理的静态资源,例如图片、字体、robots.txt 等。这些文件可以直接通过项目的根 URL 访问(例如 /favicon.ico 对应 public/favicon.ico)。
  • next.config.js: Next.js 的配置文件,用于进行更高级的配置,例如环境变量、自定义 Webpack 配置等。

第三步:创建新页面和导航

Next.js 的文件系统路由非常直观。只需在 app 目录下创建文件夹和 page.tsx 文件即可。

创建 “关于我们” 页面

  1. src/app 目录下创建一个新文件夹,命名为 about
  2. src/app/about 目录下创建一个新文件,命名为 page.tsx
  3. 打开 src/app/about/page.tsx,添加以下内容:

    “`tsx
    // src/app/about/page.tsx

    export default function AboutPage() {
    return (

    关于我们

    这是一个关于我们的页面,使用 Next.js 构建。


    );
    }
    “`

保存文件。现在,访问 http://localhost:3000/about,你将看到你创建的 “关于我们” 页面。就是这么简单!

创建导航链接

为了方便用户在页面之间切换,我们需要添加导航链接。在 Next.js 中,我们使用内置的 <Link> 组件来处理客户端导航。使用 <Link> 的好处是它会自动处理预加载(prefetching),在用户可能点击链接之前提前加载目标页面的代码,从而加快页面切换速度。

  1. 修改 src/app/page.tsx,添加一个到 “关于我们” 页面的链接:

    “`tsx
    // src/app/page.tsx
    import Link from ‘next/link’; // 导入 Link 组件
    import Image from ‘next/image’;
    import styles from ‘./page.module.css’; // 假设存在这个样式文件,create-next-app 会生成

    export default function Home() {
    return (

    Get started by editing 
    src/app/page.tsx

      <div className={styles.center}>
        {/* ... 其他内容 ... */}
      </div>
    
      <div className={styles.grid}>
        {/* ... 其他链接 ... */}
      </div>
    
      {/* 添加一个到关于页面的链接 */}
      <div style={{ marginTop: '2rem' }}>
        <Link href="/about">
          点击前往关于我们页面
        </Link>
      </div>
    </main>
    

    );
    }
    ``
    (注意:上面的代码包含了
    create-next-app` 默认生成的一些内容,你可以在其中找到合适的位置添加你的链接)

  2. 修改 src/app/about/page.tsx,添加一个回到首页的链接:

    “`tsx
    // src/app/about/page.tsx
    import Link from ‘next/link’; // 导入 Link 组件

    export default function AboutPage() {
    return (

    关于我们

    这是一个关于我们的页面,使用 Next.js 构建。

      {/* 添加一个回到首页的链接 */}
      <div style={{ marginTop: '1rem' }}>
        <Link href="/">
          返回首页
        </Link>
      </div>
    </main>
    

    );
    }
    “`

保存文件。现在你可以在首页和关于页面之间轻松导航了。

第四步:理解 Server Components 和 Client Components

Next.js 13+ App Router 的一个重要特性是引入了 React Server Components (RSC)。默认情况下,app 目录下的所有组件都是 Server Components。

Server Components (服务器组件)

  • 默认类型。
  • 在服务器上渲染,不包含 JavaScript。
  • 可以直接访问文件系统、数据库或内部 API。
  • 不支持状态 (State) 和副作用 (Effects) (如 useState, useEffect)。
  • 更小的客户端 Bundle 体积,有助于提升性能。

Client Components (客户端组件)

  • 需要通过在文件顶部添加 'use client'; 指令来标记。
  • 在浏览器中渲染,包含 JavaScript。
  • 可以访问浏览器 API (如 window, localStorage)。
  • 支持交互功能,可以使用状态和副作用。

何时使用哪种?

  • Server Components: 适合渲染不依赖用户交互或浏览器 API 的静态或动态内容,例如显示博客文章、产品列表、从数据库获取数据等。它们可以减少客户端的 JavaScript 负担。
  • Client Components: 适合需要用户交互或访问浏览器特定功能的组件,例如带有点击事件的按钮、表单输入、动画、使用 Hooks (useState, useEffect) 的组件等。

示例:创建一个 Client Component

让我们创建一个简单的计数器组件,它需要使用 useState,因此必须是一个 Client Component。

  1. src/app 目录下创建一个新文件夹,命名为 components
  2. src/app/components 目录下创建一个新文件,命名为 Counter.tsx
  3. 打开 src/app/components/Counter.tsx,添加以下内容:

    “`tsx
    // src/app/components/Counter.tsx
    ‘use client’; // 👈 标记这是一个客户端组件

    import { useState } from ‘react’; // 可以在客户端组件中使用 Hooks

    export default function Counter() {
    const [count, setCount] = useState(0);

    return (

    计数: {count}

    );
    }
    “`

  4. 现在,在 src/app/page.tsx (这是一个 Server Component) 中导入并使用这个 Client Component:

    “`tsx
    // src/app/page.tsx
    import Link from ‘next/link’;
    import Image from ‘next/image’;
    // import styles from ‘./page.module.css’; // 根据你的项目选择是否保留
    import Counter from ‘./components/Counter’; // 导入客户端组件

    export default function Home() {
    return (

    欢迎来到我的 Next.js 应用!

    这是一个首页。

      {/* 在服务器组件中渲染客户端组件 */}
      <Counter />
    
      <div style={{ marginTop: '2rem' }}>
        <Link href="/about">
          点击前往关于我们页面
        </Link>
      </div>
    </main>
    

    );
    }
    “`

保存文件,刷新首页,你将看到并可以与计数器交互了。

重要概念: Server Components 可以导入和渲染 Client Components,但 Client Components 不能直接导入和使用 Server Components。如果你需要在 Client Component 中使用 Server Component 渲染的内容,可以将 Server Component 的内容作为 props 传递给 Client Component,或者利用 composition patterns (组合模式)。

第五步:添加样式

Next.js 支持多种样式方案,包括全局 CSS、CSS Modules、CSS-in-JS 库以及与 Tailwind CSS 集成 (如果你在 setup 时选择了)。

全局样式

src/app/global.css 是放置全局样式的地方。你可以直接在这里编写 CSS,或者导入其他 CSS 文件。

“`css
/ src/app/global.css /
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

h1 {
color: #333;
}
“`

CSS Modules

CSS Modules 可以很好地解决 CSS 全局污染的问题,它会为你的类名生成唯一的哈希值。文件名需要以 .module.css 结尾。

  1. src/appsrc/app/ui (如果你创建了 UI 组件目录) 下创建一个新的 CSS Modules 文件,例如 src/app/ui/Button.module.css

    “`css
    / src/app/ui/Button.module.css /
    .button {
    padding: 10px 20px;
    background-color: #0070f3;
    color: white;
    border: none;
    border-radius: 5px;
    cursor: pointer;
    font-size: 1rem;
    }

    .button:hover {
    background-color: #0050c0;
    }
    “`

  2. 创建一个使用这个样式的 React 组件,例如 src/app/ui/Button.tsx

    “`tsx
    // src/app/ui/Button.tsx
    // 这个组件可以是一个 Client Component 如果需要交互
    // 如果只是用于样式展示,可以是 Server Component
    // 我们在这里为了演示方便,让它成为一个 Client Component
    ‘use client’;

    import styles from ‘./Button.module.css’; // 导入 CSS Modules

    interface ButtonProps {
    children: React.ReactNode;
    onClick?: () => void;
    }

    export default function Button({ children, onClick }: ButtonProps) {
    return (

    );
    }
    “`

  3. 在你的页面 (page.tsxabout/page.tsx) 中导入并使用这个按钮组件:

    “`tsx
    // src/app/page.tsx
    // … 其他导入 …
    import Button from ‘./ui/Button’; // 导入带 CSS Modules 的按钮组件

    export default function Home() {
    return (

    欢迎来到我的 Next.js 应用!

    这是一个首页。

      <Counter />
    
      <div style={{ marginTop: '1rem' }}>
        {/* 使用 Button 组件 */}
        <Button onClick={() => alert('按钮被点击了!')}>
          一个带样式的按钮
        </Button>
      </div>
    
      <div style={{ marginTop: '2rem' }}>
        <Link href="/about">
          点击前往关于我们页面
        </Link>
      </div>
    </main>
    

    );
    }
    “`

现在,你就有了一个使用 CSS Modules 样式化的按钮。

第六步:数据获取 (Data Fetching)

在 Next.js 的 App Router 中,推荐在 Server Components 中进行数据获取。这使得你可以在渲染组件之前就获取到所需的数据,从而提升性能和用户体验。

Next.js 扩展了原生的 fetch API,提供了强大的缓存和去重能力。

示例:在首页获取数据

让我们在首页获取一个简单的用户列表,并展示出来。我们将使用 JSONPlaceholder 提供的免费 API。

修改 src/app/page.tsx 文件:

“`tsx
// src/app/page.tsx
import Link from ‘next/link’;
import Image from ‘next/image’;
// import styles from ‘./page.module.css’; // 根据你的项目选择是否保留
import Counter from ‘./components/Counter’; // 导入客户端组件

// 定义用户类型 (如果使用 TypeScript)
interface User {
id: number;
name: string;
username: string;
email: string;
// … 其他属性
}

// 异步 Server Component,用于数据获取
export default async function Home() { // 👈 将组件声明为 async
// 在 Server Component 中直接使用 fetch
const res = await fetch(‘https://jsonplaceholder.typicode.com/users’);
const users: User[] = await res.json();

return (

欢迎来到我的 Next.js 应用!

这是一个首页。

  <Counter />

  <div style={{ marginTop: '2rem' }}>
    <h2>用户列表 (从 API 获取):</h2>
    <ul>
      {users.map(user => (
        <li key={user.id}>
          {user.name} ({user.email})
        </li>
      ))}
    </ul>
  </div>


  <div style={{ marginTop: '2rem' }}>
    <Link href="/about">
      点击前往关于我们页面
    </Link>
  </div>
</main>

);
}
“`

保存文件,刷新首页,你将看到从 API 获取到的用户列表显示出来了。

Next.js 的 fetch 扩展

Next.js 对原生的 fetch 进行了扩展,支持更高级的缓存控制选项:

  • cache:
    • 'force-cache' (默认): 尽可能从缓存中获取数据。
    • 'no-store': 始终重新获取数据,不使用缓存。
    • 'only-if-cached': 只从缓存中获取,如果缓存中没有则返回 undefined。
  • next:
    • { revalidate: number | false }: 设置数据的重新验证间隔(秒)。如果设置为 false,则禁用自动重新验证。
    • { tags: string[] }: 为请求打标签,以便按标签按需重新验证。

例如,如果你想每隔 60 秒重新验证一次用户数据:

tsx
const res = await fetch('https://jsonplaceholder.typicode.com/users', {
next: { revalidate: 60 } // 每 60 秒重新验证一次
});
const users: User[] = await res.json();

这种在 Server Component 中直接 await fetch 的模式非常强大,它简化了数据获取逻辑,并利用 Next.js 内置的缓存机制提高了性能。

第七步:构建和运行生产版本

开发模式 (npm run dev) 带有热更新等功能,适合开发调试。但要部署到生产环境,你需要构建一个优化过的版本。

在终端中运行:

“`bash
npm run build

或者 yarn build

或者 pnpm build

“`

这个命令会触发 Next.js 的生产构建过程。它会进行代码优化、生成静态资源、根据你的页面使用 SSR 还是 SSG 来决定渲染方式等。构建完成后,你会看到一个 .next 目录,里面包含了构建后的文件。

终端会输出每个页面的渲染方式(例如,/ 是 SSR 或 Static,/about 是 Static)。

构建完成后,你可以运行生产服务器来预览应用:

“`bash
npm start

或者 yarn start

或者 pnpm start

“`

现在,访问 http://localhost:3000 (或其他显示的端口),你看到的就是构建后的生产版本应用了。它通常比开发模式更快,并且已经过优化。

进阶探索

完成第一个 Next.js 应用的基础构建后,你还可以继续探索更多强大的功能:

  • 动态路由: 处理带有参数的路由,例如 /posts/[id]
  • API 路由: 在 src/app/api 目录下创建 RESTful API 端点。
  • Loading UI: 使用 loading.tsx 文件为路由段添加加载状态。
  • Error Handling: 使用 error.tsx 文件为路由段添加错误边界。
  • Static Assets: 如何在 public 目录中放置和使用静态资源。
  • Middleware: 在请求到达路由之前运行代码。
  • 部署: Next.js 可以轻松部署到 Vercel (由 Next.js 团队开发,提供最佳支持)、Netlify、AWS 等平台。

总结

恭喜你!你已经成功创建、运行并了解了 Next.js 的核心概念,包括:

  • 使用 create-next-app 初始化项目。
  • 理解 App Router 的文件系统路由 (app/, page.tsx, layout.tsx)。
  • 区分和使用 Server Components 和 Client Components。
  • 添加页面间导航 (<Link>)。
  • 使用全局样式和 CSS Modules。
  • 在 Server Component 中进行数据获取 (fetch)。
  • 构建和运行应用的生产版本。

这只是 Next.js 强大功能的冰山一角。通过不断实践和学习,你可以利用 Next.js 构建出高性能、可伸缩且易于维护的现代 Web 应用。

接下来,你可以尝试:

  1. 为你的应用添加更多页面和导航。
  2. 尝试获取不同类型的外部数据。
  3. 使用 CSS Modules 或 Tailwind CSS (如果安装了) 来美化你的应用。
  4. 了解如何处理动态路由和 API 路由。

祝你在 Next.js 的学习旅程中一切顺利!

发表评论

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

滚动至顶部