TypeScript 全栈项目结构最佳实践
一个清晰的项目结构是团队协作和长期维护的基础。好的目录组织能让新成员快速上手,也能让代码的职责边界一目了然。下面介绍一种基于 pnpm monorepo 的 TypeScript 全栈项目结构。
一、目录结构总览
project/
├── server/ # 后端服务
│ ├── src/
│ │ ├── api/ # 路由 & 请求处理
│ │ │ ├── auth.ts
│ │ │ ├── users.ts
│ │ │ └── index.ts
│ │ ├── service/ # 业务逻辑
│ │ │ ├── auth.service.ts
│ │ │ └── user.service.ts
│ │ ├── db/ # 数据库
│ │ │ ├── schema/ # 表结构定义
│ │ │ ├── migrations/ # 迁移文件
│ │ │ └── index.ts # 数据库连接
│ │ ├── lib/ # 工具函数 & 通用模块
│ │ │ ├── jwt.ts
│ │ │ └── logger.ts
│ │ ├── env.ts # 环境变量配置
│ │ └── main.ts # 应用入口
│ ├── Dockerfile # 后端容器构建
│ ├── package.json
│ └── tsconfig.json
│
├── cli/ # 命令行工具
│ ├── src/
│ │ ├── main.ts
│ │ └── env.ts
│ ├── package.json
│ └── tsconfig.json
│
├── web/ # 前端应用(可选)
│ ├── public/ # 不经过构建处理的静态文件
│ ├── src/
│ │ ├── assets/ # 需要构建处理的资源(图片、字体等)
│ │ ├── routes/ # 页面路由
│ │ ├── components/ # UI 组件
│ │ │ └── ui/ # 基础组件(shadcn/ui)
│ │ ├── hooks/ # 自定义 Hooks
│ │ ├── stores/ # 状态管理
│ │ ├── lib/ # 工具函数
│ │ ├── index.css # 全局样式入口
│ │ └── main.tsx
│ ├── index.html
│ ├── vite.config.ts
│ ├── Dockerfile # 前端容器构建
│ ├── package.json
│ └── tsconfig.json
│
├── test/ # 测试
│ ├── api/ # API 集成测试
│ ├── e2e/ # 端到端测试(可选)
│ │ ├── case-1/
│ │ └── case-2/
│ ├── playwright.config.ts
│ ├── vitest.config.ts
│ ├── package.json
│ └── tsconfig.json
│
├── pnpm-lock.yaml # 依赖锁定文件
├── pnpm-workspace.yaml # Workspace 配置
├── tsconfig.json # 根 TypeScript 配置
├── .env.example
└── package.json
二、核心思路
整个项目围绕 server 这个核心展开。server 提供 RESTful API,是所有功能的底层支撑,其他模块都是它的消费者:
- web — 后端 API 的前端界面封装,供人使用
- cli — 后端 API 的命令行封装,供 AI Agent 使用。例如一个 PMS 服务,CLI 提供
pms help、pms login、pms query等命令,Agent 通过 CLI 即可直接操作服务
两种使用方式,同一个底层服务。在 AI Agent 时代,CLI 的重要性会越来越高——Agent 天然适合命令行交互,迭代快、集成方便。Web 界面并非每个服务都需要。
因此这套结构有两种裁剪方式:
- 完整模式:server + cli + web + test(api + e2e)— 同时服务人和 Agent
- 精简模式:server + cli + test(api)— 去掉 web 和 e2e,专注后端和 CLI
三、各模块说明
server/ — 后端服务
- api/ — 路由层,负责请求解析、参数校验和响应返回,不含业务逻辑
- service/ — 业务逻辑层,处理核心业务规则,被 api 层调用
- db/ — 数据库层,包含 schema 定义和迁移文件,统一管理数据访问
- lib/ — 通用工具,如 JWT、日志等可复用模块
- env.ts — 环境变量配置,使用 Zod 做类型校验
cli/ — 命令行工具
对 server API 的 CLI 封装,让 AI Agent 能通过命令行直接调用后端服务。
web/ — 前端应用(可选)
- routes/ — 基于文件系统的路由组织(TanStack Router)
- components/ — UI 组件,
ui/子目录存放 shadcn/ui 基础组件 - hooks/ — 自定义 React Hooks,封装可复用逻辑
- stores/ — Zustand 状态管理
- lib/ — 工具函数,如 API 客户端、格式化等
test/ — 测试
- api/ — API 集成测试,使用 Vitest 测试完整的请求链路
- e2e/(可选)— 端到端测试,使用 Playwright 模拟真实用户操作。有 web 时才需要
四、设计要点
- 一个核心,两种消费 — server 是底层,web 给人用,cli 给 Agent 用
- Monorepo 管理 — pnpm workspace 统一管理多个包,共享依赖和 TypeScript 配置
- 按需裁剪 — web 和 e2e 是可选模块,不需要前端界面时直接去掉
- 测试独立 — 测试作为独立包存在,避免测试代码和业务代码混杂
- 配置集中 — 环境变量通过
env.ts统一管理,配合 Zod 确保类型安全