项目组织:别让代码变成一锅粥
为什么要讲项目结构?
你刚学编程的时候,所有代码都写在一个文件里,感觉挺好的。但当代码量超过 500 行,你会发现:
- 找一个函数要翻半天——"那个处理用户登录的函数在哪来着?"
- 改一个地方,另一个地方莫名其妙坏了——因为全局变量太多
- 同事问你代码结构,你说"都在 main.py 里"——然后他沉默了
好的项目结构就像整理衣柜:T 恤放一个抽屉,裤子放一个抽屉,袜子放一个抽屉。找东西的时候,一秒定位。
Python 项目结构
一个典型的 Python 项目长这样
对比一下,会发现两边长得几乎一样!好的项目结构是跨语言的——models/、services/、utils/、tests/ 这些概念到处都适用。
关键差异
| Python | JavaScript | |
|---|---|---|
| 源代码目录 | 和项目同名的文件夹 | src/ 文件夹 |
| 包标志 | 需要 __init__.py | 不需要任何标志文件 |
| 测试文件命名 | test_xxx.py | xxx.test.js 或 xxx.spec.js |
| 配置文件 | pyproject.toml | package.json |
__init__.py:Python 的"门牌号"
Python 有一个 JS 没有的概念——__init__.py。它告诉 Python:"这个文件夹是一个包(package),不只是一个普通文件夹。"
| Python | JavaScript | |
|---|---|---|
| 文件夹入口 | __init__.py | index.js |
| 必须存在? | 传统上必须(标记为包) | 不必须(但很常用) |
| 作用 | 初始化包 + 控制导出 | 集中导出(桶文件) |
| 自动识别 | import models 找 __init__.py | import "./models" 找 index.js |
绝对导入 vs 相对导入
项目大了之后,文件之间互相引用的路径会变得很复杂。两种语言的策略不同:
| Python | JavaScript | |
|---|---|---|
| 推荐方式 | 绝对导入 | 相对导入(或路径别名) |
../ 深度 | 很少超过两级 | 可能很深 ../../../ |
| 路径别名 | 不需要(绝对导入天然好用) | 需要配置(@/ 别名) |
| 导入顺序 | 标准库 > 第三方 > 本地 | 第三方 > 本地 |
JS 的相对路径有时会变成
"../../../../utils/helper.js"这种噩梦。所以很多项目会配置路径别名(@/指向src/),让导入看起来更干净。
常见的文件夹约定
不管什么语言,好的项目结构都遵循一些通用模式:
| 文件夹 | 放什么 | 例子 |
|---|---|---|
models/ | 数据结构定义 | User、Product、Order |
services/ | 业务逻辑 | 发邮件、支付、认证 |
utils/ 或 helpers/ | 通用工具函数 | 格式化日期、校验邮箱 |
routes/ 或 api/ | API 路由 | /users、/posts |
config/ | 配置 | 数据库连接、密钥 |
tests/ | 测试文件 | 单元测试、集成测试 |
types/ | 类型定义(TS) | 接口、类型别名 |
constants/ | 常量 | 状态码、错误消息 |
一个设计原则:按功能分,不按类型分
小项目(几十个文件)用"按类型分"完全没问题。但当项目变大(几百个文件),"按功能分"会让你的生活轻松很多。
入口文件的作用
每个项目都有一个"起点"——入口文件:
| Python | JavaScript | |
|---|---|---|
| 入口文件 | main.py / app.py | index.js / app.js |
| 运行方式 | python main.py | node index.js / npm start |
| 防止被误执行 | if __name__ == "__main__": | 没有内置机制(靠约定) |
| 指定入口 | pyproject.toml 的 scripts | package.json 的 main/scripts |
问 AI:"什么是 monorepo?它和传统的多仓库(multi-repo)方式有什么区别?什么时候应该用 monorepo?"
Monorepo 是近年来很火的项目组织方式——把多个相关项目放在一个仓库里。Google、Meta、微软都在用。了解一下这个趋势,对你理解大型项目的结构很有帮助。
假设你要做一个"校园二手交易平台",功能包括:
- 用户注册/登录
- 发布商品
- 搜索商品
- 私信聊天
- 订单管理
请分别设计 Python 和 Node.js 版本的项目目录结构。要求:
- 使用"按功能分"的组织方式
- 包含 models、services、routes
- 包含 config 和 utils
- 包含 tests 目录
可以让 AI 帮你生成目录树,然后和 AI 讨论:"这个结构有什么可以改进的地方?"
小结
| 概念 | Python | JavaScript |
|---|---|---|
| 包标志文件 | __init__.py | index.js(约定) |
| 源代码目录 | 同名包目录 | src/ |
| 推荐导入方式 | 绝对导入 | 相对导入 + 路径别名 |
| 入口文件 | main.py + if __name__ | index.js + package.json |
| 测试命名 | test_xxx.py | xxx.test.js |
一句话:好的项目结构就像一个整齐的衣柜——每样东西都有自己的位置,找的时候不用翻箱倒柜。 不管用 Python 还是 JS,models/、services/、utils/ 这些经典分类都是通用的。项目小的时候别过度设计,项目大了再逐步重构——这就是工程师的智慧。