前端项目结构规范
本文档是 前端应用架构 的落地实践指南,规定了架构模式在实际项目中的目录结构与文件组织方式。
统一的项目结构能够提高代码可维护性,降低新人上手成本。
SPA 项目(Vite / CRA)
适用于 React + Vite、Create React App 等单页应用项目。
完整目录结构
text
project-root/ # 项目根目录
├─ public/ # 静态资源(原样拷贝,不走编译)
│ ├─ favicon.svg
│ └─ robots.txt
├─ src/ # 源码核心目录
│ ├─ common/ # 1. 公共通用层(所有业务模块复用)
│ │ ├─ components/ # 公共组件
│ │ │ ├─ ui/ # UI基础组件(按钮、输入框等,业务无关)
│ │ │ └─ business/ # 通用业务组件(如全局通知、用户卡片)
│ │ ├─ assets/ # 公共资源(图片、字体、图标)
│ │ ├─ hooks/ # 公共 Hooks(useRequest, useForm)
│ │ ├─ utils/ # 公共工具函数(日期、字符串、加密)
│ │ ├─ styles/ # 全局样式(重置、变量、主题)
│ │ ├─ constants.ts # 全局常量
│ │ ├─ config/ # 全局配置(API配置、枚举、主题配置)
│ │ └─ types/ # 全局类型定义
│ │
│ ├─ modules/ # 2. 业务模块层(核心)
│ │ ├─ home/ # [示例] 首页模块
│ │ │ ├─ index.tsx # View
│ │ │ ├─ controller.ts # Controller
│ │ │ ├─ service.ts # Service
│ │ │ ├─ api.ts # API
│ │ │ ├─ types.ts # Types
│ │ │ └─ components/ # 模块私有组件
│ │ │
│ │ └─ order/ # [示例] 订单模块
│ │ ├─ list/ # 子模块:列表
│ │ │ ├─ index.tsx
│ │ │ ├─ controller.ts
│ │ │ └─ types.ts
│ │ └─ detail/ # 子模块:详情
│ │ ├─ index.tsx
│ │ ├─ controller.ts
│ │ └─ types.ts
│ │
│ ├─ core/ # 3. 核心配置层
│ │ ├─ router/ # 路由配置
│ │ │ └─ index.tsx
│ │ ├─ store/ # 状态管理
│ │ │ └─ index.ts
│ │ ├─ request/ # HTTP 请求库封装
│ │ │ ├─ index.ts
│ │ │ └─ interceptors.ts
│ │ └─ permission/ # 权限管理
│ │ └─ index.ts
│ │
│ ├─ App.tsx # 根组件
│ └─ main.tsx # 入口文件
│
├─ .github/ # CI/CD 配置
│ └─ workflows/
│ └─ deploy.yml
├─ scripts/ # 自动化脚本 (部署/构建)
│ ├─ deploy-local.sh
│ └─ deploy-remote.sh
├─ Dockerfile # 生产环境容器构建
├─ docker-compose.yml # 容器编排
├─ vite.config.ts # 构建工具配置
├─ tsconfig.json # TypeScript 配置
├─ package.json # 依赖管理
└─ README.md # 项目说明文档目录职责说明
1. src/common/ - 公共通用层
存放所有业务模块复用的代码。
原则:
- 只有在 两个以上模块 使用时才提取到 common
- 保持 common 的纯净,避免堆积无用代码
子目录:
| 目录 | 职责 | 示例 |
|---|---|---|
components/ui/ | UI 基础组件(业务无关) | Button, Input, Modal |
components/business/ | 通用业务组件 | UserAvatar, StatusBadge |
hooks/ | 公共 Hooks | useRequest, useAuth |
utils/ | 工具函数 | formatDate, debounce |
styles/ | 全局样式 | reset.css, variables.css |
constants.ts | 全局常量 | API_BASE_URL, MAX_FILE_SIZE |
config/ | 全局配置 | 枚举、主题配置 |
types/ | 全局类型 | User, Response |
2. src/modules/ - 业务模块层
按业务领域组织代码,每个模块内部闭环。
模块结构:
text
modules/order/
├─ index.tsx # View 层(页面入口)
├─ controller.ts # Controller 层(数据适配)
├─ service.ts # Service 层(多接口聚合,可选)
├─ api.ts # API 层(HTTP 请求)
├─ types.ts # 模块内类型定义
├─ constants.ts # 模块内常量
└─ components/ # 模块私有组件
├─ OrderItem/
│ ├─ index.tsx
│ └─ index.module.css
└─ OrderFilter/
├─ index.tsx
└─ index.module.css子模块: 当模块过大时,可以拆分子模块。
text
modules/order/
├─ list/ # 订单列表
│ ├─ index.tsx
│ ├─ controller.ts
│ └─ types.ts
└─ detail/ # 订单详情
├─ index.tsx
├─ controller.ts
└─ types.ts3. src/core/ - 核心配置层
存放应用级别的配置和基础设施代码。
| 目录 | 职责 | 示例 |
|---|---|---|
router/ | 路由配置 | React Router 配置 |
store/ | 状态管理 | Zustand/Redux 配置 |
request/ | HTTP 请求封装 | Axios 拦截器 |
permission/ | 权限管理 | 路由守卫、权限校验 |
Next.js App Router 项目
适用于 Next.js 13+ App Router 项目。
完整目录结构
text
project-root/ # 项目根目录
├─ public/ # 静态资源
│ ├─ favicon.ico
│ └─ robots.txt
├─ src/ # 源码核心目录
│ ├─ app/ # 1. 路由即模块(核心)
│ │ ├─ layout.tsx # 全局 Layout
│ │ ├─ page.tsx # 首页(可选,或使用 Route Group)
│ │ │
│ │ ├─ (home)/ # [Route Group] 首页模块
│ │ │ ├─ page.tsx # View → URL: /
│ │ │ ├─ controller.ts # Controller
│ │ │ ├─ types.ts # Types
│ │ │ └─ components/ # 模块私有组件
│ │ │
│ │ ├─ users/ # 用户模块
│ │ │ ├─ page.tsx # 列表页 → URL: /users
│ │ │ ├─ controller.ts
│ │ │ ├─ types.ts
│ │ │ ├─ components/
│ │ │ └─ [id]/ # 动态路由
│ │ │ ├─ page.tsx # 详情页 → URL: /users/:id
│ │ │ ├─ controller.ts
│ │ │ ├─ types.ts
│ │ │ └─ loading.tsx # 加载态
│ │ │
│ │ ├─ (auth)/ # [Route Group] 认证相关
│ │ │ ├─ layout.tsx # 认证页面专用布局
│ │ │ ├─ login/ # → URL: /login
│ │ │ │ └─ page.tsx
│ │ │ └─ register/ # → URL: /register
│ │ │ └─ page.tsx
│ │ │
│ │ └─ api/ # API Routes(如需要)
│ │ └─ health/
│ │ └─ route.ts
│ │
│ ├─ common/ # 2. 公共通用层
│ │ ├─ components/ # 公共组件
│ │ │ ├─ ui/
│ │ │ └─ business/
│ │ ├─ hooks/ # 公共 Hooks
│ │ ├─ utils/ # 工具函数
│ │ ├─ styles/ # 全局样式
│ │ └─ types/ # 全局类型
│ │
│ └─ core/ # 3. 核心配置层
│ ├─ request/ # HTTP 请求封装
│ │ ├─ index.ts
│ │ └─ interceptors.ts
│ └─ store/ # 状态管理
│ └─ index.ts
│
├─ .github/ # CI/CD 配置
├─ scripts/ # 自动化脚本
├─ Dockerfile # 容器构建
├─ docker-compose.yml # 容器编排
├─ next.config.ts # Next.js 配置
├─ tsconfig.json # TypeScript 配置
├─ package.json # 依赖管理
└─ README.md # 项目说明Next.js 特殊文件说明
| 文件 | 职责 | 说明 |
|---|---|---|
layout.tsx | 布局壳 | 全局/分段布局,包含 HTML 结构、SEO 元信息 |
page.tsx | 路由入口 | View 层,页面渲染逻辑 |
loading.tsx | 加载态 | 该路由段的加载占位符 |
error.tsx | 错误边界 | 该路由段的错误处理 |
not-found.tsx | 404 页面 | 该路由段的 404 展示 |
route.ts | API Route | 后端 API 端点 |
Route Groups 使用场景
Route Groups 使用 (folderName) 语法,括号不参与 URL 路径。
| 场景 | 示例 | URL | 说明 |
|---|---|---|---|
| 首页模块化 | (home)/page.tsx | / | 让首页也能用文件夹包裹 |
| 布局分组 | (marketing)/, (dashboard)/ | /about, /dashboard | 不同分组有独立 layout |
| 逻辑分组 | (auth)/login, (auth)/register | /login, /register | 相关路由放一起 |
示例:
text
app/
├─ (marketing)/
│ ├─ layout.tsx # 营销页面布局
│ ├─ about/
│ │ └─ page.tsx # URL: /about
│ └─ pricing/
│ └─ page.tsx # URL: /pricing
│
└─ (dashboard)/
├─ layout.tsx # 后台布局
├─ users/
│ └─ page.tsx # URL: /users
└─ settings/
└─ page.tsx # URL: /settings模块内部结构
基础模块
最小化的模块结构:
text
modules/user/
├─ index.tsx # View
├─ controller.ts # Controller
├─ api.ts # API
└─ types.ts # Types标准模块
包含私有组件的模块:
text
modules/order/
├─ index.tsx
├─ controller.ts
├─ service.ts # 多接口聚合(可选)
├─ api.ts
├─ types.ts
├─ constants.ts # 模块内常量
└─ components/ # 模块私有组件
├─ OrderItem/
└─ OrderFilter/复杂模块
包含子模块的大型模块:
text
modules/order/
├─ list/ # 子模块:列表
│ ├─ index.tsx
│ ├─ controller.ts
│ ├─ types.ts
│ └─ components/
│
├─ detail/ # 子模块:详情
│ ├─ index.tsx
│ ├─ controller.ts
│ ├─ types.ts
│ └─ components/
│
├─ api.ts # 共享 API
└─ types.ts # 共享 Types组件目录结构
无样式组件
简单组件可以使用单文件:
text
common/components/ui/Button.tsx有样式组件
必须使用文件夹 + index.tsx + index.module.css:
text
common/components/UserCard/
├─ index.tsx
└─ index.module.css复杂组件
包含子组件的复杂组件:
text
common/components/DataTable/
├─ index.tsx # 主组件
├─ index.module.css # 主样式
├─ TableHeader.tsx # 子组件
├─ TableRow.tsx
├─ TableCell.tsx
└─ types.ts # 组件内类型配置文件位置
根目录配置文件
text
project-root/
├─ .env.development # 开发环境变量
├─ .env.production # 生产环境变量
├─ .eslintrc.js # ESLint 配置
├─ .prettierrc # Prettier 配置
├─ .gitignore # Git 忽略文件
├─ tsconfig.json # TypeScript 配置
├─ vite.config.ts # Vite 配置
├─ next.config.ts # Next.js 配置
└─ package.json # 依赖管理部署相关文件
text
project-root/
├─ Dockerfile # 生产环境容器构建
├─ Dockerfile.dev # 开发环境容器构建
├─ docker-compose.yml # 生产环境编排
├─ docker-compose.dev.yml # 开发环境编排
└─ nginx.conf # Nginx 配置(SPA 项目)CI/CD 配置
text
.github/
└─ workflows/
├─ deploy.yml # 部署流程
└─ test.yml # 测试流程最佳实践
1. 保持目录层级扁平
避免过深的嵌套,一般不超过 4 层。
text
✅ 正确
src/modules/order/list/index.tsx
❌ 错误
src/modules/order/pages/list/views/index.tsx # 过深2. 按需创建目录
不要一开始就创建所有目录,按需添加。
text
✅ 正确
modules/user/
├─ index.tsx
└─ controller.ts
❌ 错误(过度设计)
modules/user/
├─ index.tsx
├─ controller.ts
├─ service.ts # 如果不需要多接口聚合,不要创建
├─ constants.ts # 如果没有常量,不要创建
└─ components/ # 如果没有私有组件,不要创建3. 模块独立性
每个模块应该尽可能独立,减少跨模块依赖。
typescript
✅ 正确
// modules/order/controller.ts
import { orderApi } from './api' # 模块内部引用
❌ 错误
// modules/order/controller.ts
import { userApi } from '../user/api' # 跨模块引用,增加耦合解决方案: 如果需要跨模块调用,考虑:
- 将共享逻辑提取到
src/common - 通过 API 层统一调用
- 使用事件总线解耦
4. 文件命名一致性
同一类型的文件使用统一命名:
text
✅ 正确
modules/order/controller.ts
modules/user/controller.ts
modules/product/controller.ts
❌ 错误
modules/order/controller.ts
modules/user/userController.ts # 不一致
modules/product/productCtrl.ts # 不一致