第 12 章:最佳实践与项目结构组织

第 12 章:最佳实践与项目结构组织


12.1 推荐的项目结构

Next.js 默认结构简洁,但项目增大后建议进行模块化管理:

bash 复制代码
/project-root
├── public/             # 静态资源
├── pages/              # 页面入口(可拆分子模块)
│   ├── index.tsx
│   ├── about.tsx
│   └── blog/
│       ├── index.tsx
│       └── [slug].tsx
├── components/         # UI 组件
│   └── shared/
├── layouts/            # 页面布局(Layout)
├── hooks/              # 自定义 Hook
├── lib/                # 工具方法,如 fetcher、apiClient
├── services/           # 接口逻辑封装(如 REST、GraphQL 调用)
├── store/              # 状态管理(如 zustand、redux)
├── styles/             # 样式文件(CSS / SCSS / Tailwind 配置)
├── constants/          # 常量配置
├── types/              # 类型定义(TypeScript)
└── middleware.ts       # 中间件(Edge Functions)

12.2 页面与组件分离

  • 页面只负责布局与加载数据
  • 将复用 UI 拆到 components/
  • 将页面逻辑 Hook 拆到 hooks/
  • 接口访问封装在 services/

这样做的好处:

  • 更清晰的职责划分
  • 更易测试和复用
  • 更利于多人协作开发

12.3 布局管理 Layout 模式

可以为不同页面定义统一或动态布局。

✅ 方法 1:在 _app.tsx 中包裹 Layout

tsx 复制代码
// pages/_app.tsx
export default function App({ Component, pageProps }) {
  const getLayout = Component.getLayout || ((page) => <DefaultLayout>{page}</DefaultLayout>);
  return getLayout(<Component {...pageProps} />);
}

✅ 页面中定义布局:

tsx 复制代码
// pages/about.tsx
import { CustomLayout } from '@/layouts/CustomLayout';

function AboutPage() {
  return <div>About Us</div>;
}

AboutPage.getLayout = function getLayout(page) {
  return <CustomLayout>{page}</CustomLayout>;
};

export default AboutPage;

12.4 API 请求封装

推荐封装统一的 fetcher 或 API 客户端:

ts 复制代码
// lib/fetcher.ts
export async function fetcher(url: string, options = {}) {
  const res = await fetch(url, { ...options });
  if (!res.ok) throw new Error('Network error');
  return res.json();
}

结合 SWR:

tsx 复制代码
const { data, error } = useSWR('/api/user', fetcher);

12.5 样式管理建议

技术栈 推荐用途
Tailwind CSS 推荐(可配置、响应式强)
CSS Modules 局部组件样式
SCSS 如果已有习惯可以保留
styled-components / Emotion 适合需要 JS-in-CSS 的项目

尽量避免:

  • 全局样式过多
  • 同时使用多种 CSS 方案导致冲突

12.6 状态管理最佳实践

  • 🔸 小型应用优先使用 React 原生状态(useState, useContext

  • 🔹 中大型项目推荐使用:

    • Zustand(轻量推荐)
    • Redux Toolkit(需要全局状态同步)
    • Jotai / Recoil(原子状态管理)

示例(Zustand):

ts 复制代码
import { create } from 'zustand';

const useUserStore = create((set) => ({
  user: null,
  setUser: (user) => set({ user }),
}));

12.7 使用别名简化路径(推荐)

📄 jsconfig.jsontsconfig.json

json 复制代码
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/components/*": ["components/*"],
      "@/hooks/*": ["hooks/*"],
      "@/lib/*": ["lib/*"]
    }
  }
}

📦 组件中这样使用:

tsx 复制代码
import Header from '@/components/Header';

12.8 国际化(i18n)支持(可选)

Next.js 原生支持多语言:

📄 next.config.js 中配置:

js 复制代码
i18n: {
  locales: ['en', 'zh'],
  defaultLocale: 'zh',
}

📄 页面自动按语言路径加载:

bash 复制代码
/en/about
/zh/about

12.9 安全 & 性能最佳实践

项目 建议
环境变量 使用 .env.local、避免暴露敏感值
SSR 缓存 配合 CDN 或 ISR
图片优化 使用 <Image /> 自动压缩
防止 XSS 使用 dangerouslySetInnerHTML 时注意清洗
懒加载 延迟加载大组件、图片资源
自动预加载 <Link /> 默认开启
分包优化 利用动态导入 import('./BigComp')

✅ 小结

内容 推荐实践
项目结构 模块化 + 按功能组织
页面职责 分离视图、逻辑、服务
布局复用 getLayout() + 多布局支持
状态管理 小用原生,大用 Zustand 等
请求封装 lib/fetcher.ts + SWR
样式管理 Tailwind / CSS Modules 优先
安全性能 懒加载、XSS防护、缓存、路径别名
相关推荐
IT_陈寒2 小时前
SpringBoot这个自动配置坑我跳了三次
前端·人工智能·后端
kyriewen2 小时前
我用 AI 一周写完了整个项目,上线第一天就崩了——这是我踩过最贵的 5 个坑
前端·javascript·ai编程
牧艺2 小时前
从零到协同:构建类飞书在线文档系统的五个技术重难点
前端·人工智能
红尘散仙3 小时前
想写一个像样的终端 App?试试把 React 的开发体验搬进 Rust TUI
前端·rust
袋鼠云数栈UED团队3 小时前
一套 Spec-First 的 AI 编程工作流
前端·人工智能
袋鼠云数栈前端4 小时前
一套 Spec-First 的 AI 编程工作流
前端·ai+
angerdream4 小时前
Android手把手编写儿童手机远程监控App之vue3 路由守卫
前端
不服老的小黑哥4 小时前
AI规范驱动编程-harness工程项目实战
前端
vivo互联网技术4 小时前
从 Web 到桌面:基于 Tauri 2.0 + Vue 3 打造 vivo 线下门店「大头贴」拍照体验系统
前端·rust
光影少年4 小时前
React 合成事件机制、和原生事件区别、事件冒泡阻止
前端·react.js·掘金·金石计划