第 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_陈寒20 分钟前
Java并发编程避坑指南:7个常见陷阱与性能提升30%的解决方案
前端·人工智能·后端
HBR666_34 分钟前
AI编辑器(FIM补全,AI扩写)简介
前端·ai·编辑器·fim·tiptap
excel39 分钟前
一文读懂 Vue 组件间通信机制(含 Vue2 / Vue3 区别)
前端·javascript·vue.js
JarvanMo42 分钟前
Flutter 应用生命周期:使用 AppLifecycleListener 阻止应用崩溃
前端
我的xiaodoujiao2 小时前
从 0 到 1 搭建 Python 语言 Web UI自动化测试学习系列 9--基础知识 5--常用函数 3
前端·python·测试工具·ui
李鸿耀4 小时前
Flex 布局下文字省略不生效?原因其实很简单
前端
皮蛋瘦肉粥_1215 小时前
pink老师html5+css3day06
前端·css3·html5
华仔啊9 小时前
前端必看!12个JS神级简写技巧,代码效率直接飙升80%,告别加班!
前端·javascript
excel9 小时前
dep.ts 逐行解读
前端·javascript·vue.js
爱上妖精的尾巴9 小时前
5-20 WPS JS宏 every与some数组的[与或]迭代(数组的逻辑判断)
开发语言·前端·javascript·wps·js宏·jsa