在 React 项目中组织文件和目录对于可维护性、可扩展性和导航的便利性至关重要。本文探讨了不同规模的 React 项目的一般架构和文件夹结构,并为每个级别提供了清晰的演示。
1️⃣ 第 1 级:按“文件类型”分组
这种结构的特点是简单——根据文件类型进行分组:
└── src/
├── assets/
├── api/
├── configs/
├── components/
│ ├── SignUpForm.tsx
│ ├── Employees.tsx
│ ├── PaymentForm.tsx
│ └── Button.tsx
├── hooks/
│ ├── usePayment.ts
│ ├── useUpdateEmployee.ts
│ ├── useEmployees.ts
│ └── useAuth.tsx
├── lib/
├── services/
├── states/
└── utils/
项目规模:小型至中型
优点:简单直接
缺点:
会迅速膨胀并变得难以维持
业务关注点无分离
假设您有很多与支付相关的代码。有一天整个业务发生变化或不再需要,替换或删除它有多容易?使用这种文件夹结构,您必须浏览每个文件夹及其中的文件才能进行必要的更改。如果项目继续增长,它很快就会变成维护地狱,而且随着时间的推移只会变得更糟。
2️⃣ 第二级:按“文件类型”和功能分组
随着项目的发展,“2 级”结构引入了按每种类型中的特性进行分组的功能:
└── src/
├── assets/
├── api/
├── configs/
├── components/
│ ├── auth/
│ │ └── SignUpForm.tsx
│ ├── payment/
│ │ └── PaymentForm.tsx
│ ├── common/
│ │ └── Button.tsx
│ └── employees/
│ ├── EmployeeList.tsx
│ └── EmployeeSummary.tsx
├── hooks/
│ ├── auth/
│ │ └── useAuth.ts
│ ├── payment/
│ │ └── usePayment.ts
│ └── employees/
│ ├── useEmployees.ts
│ └── useUpdateEmployee.ts
├── lib/
├── services/
├── states/
└── utils/
项目规模:中型至大型
优点:
简单直接
物品按特征分组
缺点:
与功能相关的逻辑仍然分布在多个文件夹类型中
现在让我们回到需要修改或删除支付模块的问题陈述。有了这个结构,现在做起来就容易多了。
如果您不知道选择什么,我推荐“2 级”文件夹结构。
3️⃣ 第 3 级:按功能 / 模块分组
对于较大的项目,“3 级”结构提供了高度模块化的方法,为每个模块内应用程序的不同方面定义了明确的界限:
└── src/
├── assets/
├── modules/
| ├── core/
│ │ ├── components/
│ │ ├── design-system/
│ │ │ └── Button.tsx
│ │ ├── hooks/
│ │ ├── lib/
│ │ └── utils/
│ ├── payment/
│ │ ├── components/
│ │ │ └── PaymentForm.tsx
│ │ ├── hooks/
│ │ │ └── usePayment.ts
│ │ ├── lib/
│ │ ├── services/
│ │ ├── states/
│ │ └── utils/
│ ├── auth/
│ │ ├── components/
│ │ │ └── SignUpForm.tsx
│ │ ├── hooks/
│ │ │ └── useAuth.ts
│ │ ├── lib/
│ │ ├── services/
│ │ ├── states/
│ │ └── utils/
│ └── employees/
│ ├── components/
│ │ ├── EmployeeList.tsx
│ │ └── EmployeeSummary.tsx
│ ├── hooks/
│ │ ├── useEmployees.ts
│ │ └── useUpdateEmployee.ts
│ ├── services/
│ ├── states/
│ └── utils/
└── ...
项目规模:大型且复杂
优点:
内容按照功能/模块清晰地分组
特征/模块是现实世界中对象的清晰表示
缺点:
您必须充分了解业务逻辑才能做出正确的分组决策
有了这个,如果您要删除或修改付款逻辑,您会立即知道从哪里开始。
赋予文件夹名称一致的含义
无论结构级别如何,某些文件夹名称都应具有特定含义。文件夹名称的含义可能因您的偏好或项目惯例而异。
以下是我通常认为的文件夹名称:
UI 组件
组件:React 组件——主要的 UI 构建块。
设计系统:基于设计系统的基本 UI 元素和模式。
图标:用于内联使用的 SVG 图标。
React 具体
hooks:用于共享逻辑的自定义 React hooks。
hocs:React 高阶组件。
contexts / provider:包含 React Contexts 和 Providers。
实用程序和外部集成
utils:与业务逻辑或任何技术无关的通用逻辑实用程序,例如字符串操作、数学计算等。
lib:与某些技术相关的实用程序,例如 DOM 操作、HTML 相关逻辑、localStorage、IndexedDB 等。
plugins:第三方插件(例如 i18n、Sentry 等)
业务逻辑
服务:封装主要业务和应用逻辑。
helpers:提供特定于业务的实用程序。
样式
样式:包含(全局)CSS 或 CSS-in-JS 样式。
TypeScript 和配置
类型:用于通用 TypeScript 类型、枚举和接口。
configs:应用程序的配置(例如环境变量)
constants:常量,不变的值(例如
export const MINUTES_PER_HOUR = 60
)。
服务器通信
api:用于与服务器通信的逻辑。
graphql:GraphQL 特定的代码。
状态管理
states / store:全局状态管理逻辑(Zustand、Valtio、Jotai 等)
Reducers、Store、Actions、Selectors:Redux 特定的逻辑
路由
路线/路由器:定义路线(如果您使用 React Router 或类似的东西)。
页面:定义页面的入口点组件。
测试
测试:针对您的代码进行单元测试和其他类型的测试。
🏁 结论
在 React 项目中选择正确的文件夹结构至关重要,并且应基于项目的规模和复杂性。虽然“级别 1”可能足以满足小型项目的需求,但“级别 2”和“级别 3”为中型和大型项目提供了更有组织和模块化的结构。就我个人而言,我经常推荐“级别 2”文件夹结构。此外,了解常见的文件夹名称有助于在 React 应用程序中保持一致且直观的架构。