前言
随着 Vue3 成为主流,越来越多团队开始重新思考一个问题:
大型项目应该如何组织目录结构?
很多项目在刚开始时,目录都非常简单。
例如:
src
├── api
├── assets
├── components
├── hooks
├── router
├── stores
├── styles
├── utils
├── views
这种结构对于十几个页面的小项目没有问题。
但是,当项目逐渐发展到:
- 几百个页面
- 数十名开发者
- 多个业务模块
- 长期维护
它的问题会越来越明显。
近年来,越来越多团队开始采用 Feature First(按业务模块组织) 的方式,而不是传统的按文件类型分类。
本文将深入分析两种目录结构的区别,以及为什么 Feature First 更适合现代前端工程。
传统目录结构的问题
按类型分类,是 Vue2 时代最常见的方式。
例如:
src
├── api
├── components
├── hooks
├── utils
├── views
假设现在开发一个订单模块。
你可能需要修改:
views/order
api/order
hooks/useOrder
types/order
utils/order
components/order
一个功能散落在六七个目录中。
对于开发者来说:
需要频繁切换目录。
对于 AI 工具来说:
也更难理解:
哪些文件属于同一个业务。
什么是 Feature First?
Feature First 的核心思想非常简单:
按业务,而不是按技术分类。
例如:
src
├── features
│ ├── order
│ ├── user
│ ├── payment
│ └── dashboard
每个模块内部:
order
├── api
├── components
├── composables
├── pages
├── types
├── utils
└── index.ts
这样:
订单相关的一切。
都在一个目录里。
为什么越来越多团队采用 Feature First?
第一:业务边界更加清晰
最大的优势就是:
模块之间天然隔离。
例如:
用户模块:
不会轻易依赖订单模块。
这种结构天然鼓励:
高内聚。
低耦合。
第二:更适合多人协作
假设:
团队有:
A
负责订单。
B
负责支付。
C
负责用户。
采用 Feature First。
大家几乎不会修改同一个目录。
Git 冲突明显减少。
第三:AI 更容易理解项目
这一点是近几年最大的变化。
例如:
Cursor。
Claude Code。
Codex。
都会分析整个项目。
如果目录结构:
api
utils
components
views
AI 很难判断:
哪些文件属于同一个业务。
如果采用:
features/user
features/order
features/payment
AI 理解速度会明显提升。
Feature First 是否意味着所有代码都放进去?
不是。
真正推荐的是:
业务代码放 Feature。
公共能力继续放全局。
例如:
src
├── features
├── shared
├── core
├── router
├── assets
其中:
shared:
存放:
Button。
Modal。
Table。
Loading。
真正的公共组件。
不要为了追求 Feature First。
把所有东西都复制一份。
API 如何组织?
很多项目:
所有接口:
全部放:
api/
最终:
user.ts
user2.ts
user-final.ts
越来越乱。
推荐:
features/user/api
features/order/api
业务和接口放在一起。
维护成本更低。
Composable 应该放哪里?
很多项目:
所有 Hook:
放:
composables/
推荐:
业务 Hook:
放 Feature。
例如:
features/user/composables/useUser.ts
只有真正通用的:
例如:
useDebounce
useLocalStorage
useClipboard
才放:
shared/composables
Feature First 的缺点
任何架构都有边界。
Feature First 也一样。
例如:
小项目:
只有:
5 个页面。
Feature First:
反而可能:
目录过深。
维护成本增加。
因此:
不要为了架构而架构。
项目规模。
才是决定因素。
推荐目录结构
对于 Vue3 项目,我更推荐:
src
├── app
├── assets
├── core
├── features
│ ├── auth
│ ├── dashboard
│ ├── order
│ ├── product
│ └── user
├── router
├── shared
│ ├── components
│ ├── composables
│ ├── utils
│ └── types
├── stores
└── main.ts
其中:
app:
负责应用启动。
core:
负责核心能力。
shared:
负责公共资源。
features:
负责业务。
职责清晰。
未来扩展也更容易。
如何从旧项目迁移?
不建议:
一次性全部重构。
推荐:
新增模块:
直接采用:
Feature First。
老模块:
逐步迁移。
这样:
风险最低。
也更符合长期演进原则。
总结
Feature First 并不是一种新的技术。
它更像是一种工程化思想。
随着项目规模扩大、AI 工具普及以及团队协作复杂度提升,按业务组织代码已经成为越来越多大型前端项目的选择。
它不能解决所有问题,但能够让代码结构更加清晰、模块边界更加明确,也更容易被开发者和 AI 工具共同理解。
X记录空间