为了账号安全,请及时绑定邮箱和手机立即绑定

掌握 Next.js 应用路由器:构建应用的最佳实践

Next.js 已经成为领先的 React 框架之一,为开发者提供了高性能、灵活性和易用性的无缝结合。随着 App Router 的引入,Next.js 又向前迈进了一步,提供了更直观和强大的路由机制。无论您是在构建个人博客还是大型企业应用,有效地组织您的 Next.js 项目是对于项目的可维护性、可扩展性以及开发者体验来说至关重要的。

在本文中,我们将探讨使用App Router在Next.js应用中组织项目的最佳实践,确保您的项目既有序又高效,还易于导航。

目录:
  1. 了解 Next.js 应用路由器
  2. 项目结构概览
  3. 整理页面和路由
  4. 高效管理组件
  5. 样式策略与技巧
  6. 状态管理实践
  7. 优化性能
  8. 测试和质量保证
  9. 部署注意事项
  10. 总结
初探 Next.js App 路由器

在深入了解结构化之前,了解App Router为Next.js带来了什么好处是很重要的。App Router通过引入以下功能增强了Next.js的路由能力:

  • 嵌套路由:支持复杂的嵌套路由层级结构,使用嵌套布局。
  • 动态路由:简化了动态URL的创建过程。
  • 服务器组件:允许在服务器端渲染组件,从而提升性能。
  • 增强的数据获取:提供更高效的数据获取方法,减少客户端的负载。

理解这些功能对于在你的项目结构中有效利用App Router来说是至关重要的。

项目结构简介

一个组织良好的项目结构可以提高可读性、可维护性和可扩展性。这里是一个推荐的目录布局,用于使用App Router的Next.js应用程序。

    my-nextjs-app/  
    ├── 应用/  # 应用布局和页面
    │   ├── layout.js  
    │   ├── page.js  
    │   ├── 仪表盘/  # 仪表盘组件和页面
    │   │   ├── layout.js  
    │   │   ├── page.js  
    │   │   └── 设置/  # 设置页面
    │   │       └── page.js  
    │   └── 博客/  # 博客组件和页面
    │       ├── layout.js  
    │       ├── page.js  
    │       └── [slug]/  # 博客文章页面
    │           └── page.js  
    ├── 组件/  # 通用组件
    │   ├── Header.js  
    │   ├── Footer.js  
    │   └── ...   
    ├── 样式/  # 样式文件
    │   ├── globals.css  
    │   └── ...  
    ├── 公共/  # 公共文件
    │   ├── images/  
    │   └── ...   
    ├── 库/  # 库文件
    │   ├── api.js  
    │   └── ...   
    ├── 钩子/  # 钩子文件
    │   ├── useAuth.js  
    │   └── ...   
    ├── 测试/  # 测试文件
    │   ├── 组件/  
    │   └── ...   
    ├── package.json 包文件  # 包文件配置
    ├── next.config.js 配置文件  # Next.js 配置文件
    └── ...
《重要文件和目录》
  • app/ : 包含所有利用 App Router 的路由和布局。
  • components/ : 可重用的 UI 组件。
  • styles/ : 全局样式和组件样式。
  • public/ : 静态资源,如图片、字体等。
  • lib/ : 工具函数和库文件。
  • hooks/ : 自定义的 React 钩子函数。
  • tests/ : 应用程序各部分的测试。
整理页面和路由

使用 App Router,Next.js 鼓励使用基于文件的路由系统,其中目录结构与 URL 结构相匹配。以下是有效组织你的页面和路由的方法:

嵌套的路由设置和布局设计

利用嵌套路由来创建分层布局。例如,仪表板区域有自己的独立布局,与其他主应用程序布局区分开来。

    app/  
    ├── layout.js           // 主应用布局文件  
    ├── page.js             // 主页  
    ├── dashboard/  
    │   ├── layout.js       // 仪表盘特定布局  
    │   ├── page.js         // 仪表盘首页  
    │   └── settings/  
    │       └── page.js     // 仪表盘设置
动态的路由

可以使用括号创建文件夹来处理动态内容。比如,可以使用 /blog/[slug] 来查看博客文章。例如,可以通过 /blog/[slug] (例如: /blog/2023-01-01-新年快乐) 来访问。

看看这个文件夹结构,`app/`(应用目录)下面有个 `blog/`(博客目录)文件夹,里面有一个动态的 `[slug]`(文章标识符)文件夹,最后是 `page.js`(页面文件)。

page.js 文件中。

    export default function BlogPost({ params }) {  
      const { slug } = params;  
      // 根据这个slug来获取和展示博客帖子  
    }
默认路由

对于需要匹配多个部分参数的路由,可以使用[...param]语法。

    app文件夹/  
    └── docs文件夹/  
        └── [...slug]/ (此处的[...slug]代表一个变量或占位符)  
            └── page.js (页面的JavaScript文件)

这种配置可以处理如 /docs/intro/getting-started 这样的 URL。

要有效管理组件

组件的组织对于重用和维护来说非常重要。

原子设计理念

采用原子设计原则(Atomic Design Principles)来划分组件:

  • 原子:基本构建块,如按钮、输入。

  • 分子:包含原子的功能单元。

  • 有机体:由分子和原子组成的复杂UI部分。

  • 模板:页面级结构。

  • 页面:具体的数据填充模板。

项目目录结构如下:

    components/  # 组件目录 (component directory)
    ├── atoms/  # 原子组件 (atomic components)
    │   ├── Button.js  # 按钮组件 (button component)
    │   └── Input.js  # 输入框组件 (input component)
    ├── molecules/  # 分子组件 (molecular components)
    │   ├── FormGroup.js  # 表单组组件 (form group component)
    │   └── Card.js  # 卡片组件 (card component)
    ├── organisms/  # 有机体组件 (organism components)
    │   ├── Header.js  # 头部组件 (header component)
    │   └── Footer.js  # 底部组件 (footer component)
    └── ...  # 省略其他文件 (omitting other files)
组件命名规范与文件结构

使用清晰一致的命名规则。例如,组件使用Button.js,对应的样式文件则使用Button.module.css

// components/Button/Button.js
import 样式名称 from './Button.module.css';

export default function Button({ children, onClick }) {
  return (
    <button className={样式名称.button} onClick={onClick}>
      {children}
    </button>
  );
}
样式技巧

选择合适的样式方案会影响你的开发工作流程,会直接影响你的开发流程和应用性能。

CSS 模块化

Next.js 内置支持 CSS 模块,使得 CSS 可以实现模块化和范围限定。

    组件文件夹/  
    └── 原子文件夹/  
        └── Button.module.css [按钮模块CSS文件]
带样式的组件(CSS-in-JS)

如果你需要动态样式和主题化,你可以试试 Styled Components 或 Emotion 这样的库。

// components/按钮/Button.js
import styled from 'styled-components';

const StyledButton = styled.button`
  background-color: #0070f3;
  color: white;
  padding: 0.5rem 1rem;
  border: none;
  border-radius: 4px;
  cursor: pointer;
`;

export default function Button({ children, onClick }) {
  return <StyledButton onClick={onClick}>{children}</StyledButton>;
}
Tailwind CSS (译为“尾风CSS”)

Tailwind 提供了基于工具类的 CSS 类,帮助你在不离开 HTML 的情况下快速进行样式调整。

    // components/原子/Button.tsx
    export default function Button({ children, onClick }) {
      // 背景色为蓝色,文字为白色,内边距为4,外边距为2,圆角,悬停时背景色加深
      return (
        <button
          className="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600"
          onClick={onClick}
        >
          {children}
        </button>
      );
    }
全局样式设置

使用 globals.css 文件来设定基础样式和全局配置。

    /* 样式/全局.css */
    body { /* 页体 */ }
      margin: 0;
      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen,  
        Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; /* 字体系列解释可以在此添加 */

在你的主布局文件中导入它。

    // app/layout.js  
    import '../styles/globals.css';  

    export default function RootLayout({ children }) {  
      return (  
        <html lang="en">  
          <body>{children}</body>  
        </html>  
      );  
    }

    // app/layout.js  
    import '../styles/globals.css';  

    导出默认函数 RootLayout({ children }) {  
      返回 (  
        <html lang="en">  
          <body>{children}</body>  
        </html>  
      );  
    }
状态管理的最佳实践

有效管理状态确保应用程序既可预测又易于调试。

使用React Hooks进行局部状态管理

可以使用 React 内置的钩子,如 useStateuseReducer,来处理组件级别的状态。

    import { useState } from 'react';  

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

      return (  
        <div>  
          <p>{count}</p>  
          <button onClick={() => setCount(count + 1)}>加一</button>  
        </div>  
      );  
    }
使用Context API来管理全局状态:

为了在多个组件间共享状态,可以使用 React 的 Context API。

    // context/AuthContext.js
    import { createContext, useState } from 'react';

    // 用于创建认证上下文和提供用户状态的函数
    export const AuthContext = createContext();
    export function 认证提供者({ 子元素 }) {
      // const 和 let 关键字用于声明变量
      const [user, setUser] = useState(null);

      return (
        <AuthContext.Provider value={{ user, setUser }}>
          {子元素}
        </AuthContext.Provider>
      );
    }

将你的应用放入提供程序中:

    // app/layout.js 文件中,我们从../context/AuthContext导入AuthProvider组件
    import { AuthProvider } from '../context/AuthContext';

    // 在RootLayout组件中,我们渲染一个html标签,设置lang属性为"en"
    export default function RootLayout({ children }) {
      return (
        <html lang="en">
          <body>
            // 在body标签内部,我们使用AuthProvider组件包裹children
            <AuthProvider>
              {children}
            </AuthProvider>
          </body>
        </html>
      );
    }
状态管理库工具

面对复杂的状态需求时,可以考虑用Redux、Zustand或Recoil这些库。

    // 使用Zustand状态管理库
    import create from 'zustand';  

    const useStore = create(set => ({  
      // 设置用户状态
      user: null,  
      setUser: (user) => set({ user }),  
    }));  
    export default useStore;
提升性能:

优化性能可以带来流畅的用户体验和更好的搜索排名。

代码分割(Code Splitting)与延迟加载

Next.js框架自动分割代码,但你可以通过动态导入进一步优化代码。

    import dynamic from 'next/dynamic';  

    const HeavyComponent = dynamic(() => import('../components/HeavyComponent'), {  
      loading: () => <p>正在加载...</p>,  
    });
图片优化

使用 Next.js 的 Image 组件来实现优化的图片加载。

    import Image from 'next/image';  

    export default function Profile() {  
      return (  
        <Image  
          class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="/images/profile.jpg"  
          alt="个人资料照片"  
          width={200}  
          height={200}  
        />  
      );  
    }
缓存和内容分发网络(CDN)

利用缓存策略和内容分发网络 (CDNs) 来高效地提供静态资源。

基于服务器端渲染(SSR)和静态站点生成(SSG)

根据内容的动态特性,选择 SSR 或 SSG,这样可以在性能和新鲜度之间取得平衡。

    // pages/index.js  
    export async function 获取静态属性() {  
      const data = await 获取数据();  
      return {  
        props: { data },  
        revalidate: 60, // 每 60 秒重新验证一次  
      };  
    }
测试和质量保障

实施测试确保你的应用程序保持稳定且没有回退问题。

单元测试

可以利用 Jest 和 React Testing Library 等来做单元测试。

    // tests/components/Button.test.js  
    import { render, screen, fireEvent } from '@testing-library/react';  
    import Button from '../../components/atoms/Button';  

    test('按钮渲染并处理点击事件', () => {  
      const handleClick = jest.fn();  
      render(<Button onClick={handleClick}>点击这里</Button>);  

      const button = screen.getByText('点击这里');  
      fireEvent.click(button);  // 模拟点击  

      expect(handleClick).toHaveBeenCalledTimes(1);  // 确保点击事件被正确处理一次  
    });
集成测试

我们来进行一下集成测试吧。

检验你应用程序的不同部分是如何协同工作的。

    // tests/pages/HomePage.test.js
    import { render, screen } from '@testing-library/react';
    import HomePage from '../../app/page';

    test('它应渲染包含头部和底部的内容', () => {
      render(<HomePage />);
      expect(screen.getByText('欢迎')).toBeInTheDocument();
      expect(screen.getByText('底部')).toBeInTheDocument();
    });
端到端测试

可以使用 Cypress 或 Playwright 等工具进行端到端测试,以模拟用户交互。

    // cypress/integration/home.spec.js
    describe('首页页面', () => {
      it('可以正常加载', () => {
        cy.visit('/');
        // 访问首页并检查'欢迎'文本是否存在并可见
        cy.contains('欢迎').should('存在并可见');
      });
    });
部署时的一些考虑.

高效地部署您的 Next.js 应用程序可以确保最小的停机时间和最佳的性能表现。

Vercel

Vercel,这款由同样开发 Next.js 的团队创建的产品,提供无缝部署,并且优化了性能。

其他平台:

你也可以在 Netlify、AWS、或 DigitalOcean 等平台上的部署。确保 SSR 和 API 路由的正确设置。

环境变量

通过环境变量来处理敏感数据。

    # .env.local  
    NEXT_PUBLIC_API_URL=https://api.example.com  
    # 密钥如下
    SECRET_KEY=你的密钥

在你的应用中访问它们:

    const apiUrl = process.env.NEXT_PUBLIC_API_URL; // apiUrl 用于存储从环境变量获取的 API 地址
持续集成与持续交付 (CI/CD)

搭建CI/CD流水线,利用GitHub Actions、GitLab CI等工具,以自动化测试与部署,例如利用GitHub Actions、GitLab CI或其他工具。

    # .github/workflows/ci.yml
    name: CI

    on:
      push:
        branches: [ main ]
    jobs:
      build:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v2
          - name: 安装依赖项
            run: npm install
          - name: 运行单元测试
            run: npm test
          - name: 构建项目
            run: npm run build
最后

使用 App Router 结构化您的 Next.js 应用程序对于创建可扩展、易维护且高性能的 web 应用程序来说非常重要。遵循本指南中提到的最佳实践——从项目结构的组织和组件管理到性能优化和强大测试的实施,您能够充分利用 Next.js 的全部功能,并提供出色的用户体验。

拥抱这些实践以简化您的开发工作流程,促进团队间的协作,并确保您的应用程序能够经受住不断演变的网络环境的考验。

编程愉快!如果你觉得这份指南有用,不妨分享给你的朋友们,并在下面留言评论。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消