第 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防护、缓存、路径别名
相关推荐
萌萌哒草头将军17 分钟前
🚀🚀🚀 Webpack 项目也可以引入大模型问答了!感谢 Rsdoctor 1.2 !
前端·javascript·webpack
小白的代码日记20 分钟前
Springboot-vue 地图展现
前端·javascript·vue.js
teeeeeeemo22 分钟前
js 实现 ajax 并发请求
开发语言·前端·javascript·笔记·ajax
OEC小胖胖36 分钟前
【CSS 布局】告别繁琐计算:CSS 现代布局技巧(gap, aspect-ratio, minmax)
前端·css·web
Sword9943 分钟前
🎮 AI编程新时代:Trae×Three.js打造沉浸式3D魔方游戏
前端·ai编程·trae
谜亚星1 小时前
vue和react组件更新的一点思考
前端·前端框架
清秋1 小时前
全网最全 ECMAScript 攻略( 更新至 ES2025)
前端·javascript·ecmascript 6
puffysang331 小时前
Android paging3实现本地缓存加载数据
前端
拉罐1 小时前
React Query:彻底解决 React 数据获取难题的强大利器
前端
一涯2 小时前
用python写一个抓取股市关键词的程序
前端·python