1. 前言
Go 官方没有项目布局(项目结构)要求,但是社区推崇清晰、模块化的布局,对于中大型项目推荐使用一些最佳实践。
如果我们尝试学习 Go,或者我们正在为自己建立一个 PoC 或一个玩具项目,关心项目布局是没啥必要的。建议从简单的事情开始,一个 main.go 文件绰绰有余。
随着项目的增长,我们需要代码结构良好非常重要,否则我们最终会得到一个凌乱的代码,这其中就包含大量隐藏的依赖项和全局状态。这时候,我们就需要考虑项目布局和管理包/库的方法。
也就是说,项目布局应该取决于项目的大小、复杂程度、团队偏好和管理需求。
本文中,我们学习Go项目布局的最佳实践。
参考文档:
2. 获取一个标准项目布局
1
| git clone https://github.com/golang-standards/project-layout.git myproject
|
克隆 Standard Go Project Layout 项目,保留我们需要的内容,删除其他所有的内容!
3. 中大型项目布局说明
以下是一个推荐的Go项目结构:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| . ├── cmd # 程序的主入口点所在的包,每个应用程序的入口文件都放在这个目录下的子目录中。 │ └── myapp # 程序名称作为目录名 │ └── main.go # 主程序文件(入口程序文件),只有一个入口程序文件时建议直接放入根目录 ├── pkg # 可以被外部应用程序导入使用的库代码(共享代码)。 │ └── mypubliclib # 可复用的公共库代码 ├── internal # 只能被本项目使用的库代码(私有代码)。 │ ├── api # 存放API相关的代码,例如存放HTTP客户端和服务器逻辑。 │ ├── service # 核心业务逻辑实现 │ ├── config # 配置文件加载及解析 │ └── pkg/myprivatelib # 可复用的私有库代码 ├── api # 存放API协议定义文件,如OpenAPI/Swagger规格、protobuf文件等。 ├── web # Web应用特定的组件,例如静态Web资产、服务器端模板等。 ├── assets # 项目中使用的其他资源(图像、logo 等)。 ├── configs # 配置文件模板或默认配置。 ├── scripts # 存放构建、安装、分析、Linting等操作的脚本。 ├── deployments # 存放部署相关的配置文件和脚本(比如Dockerfile、Kubernetes.yaml等) ├── test # 外部测试的额外资料和数据 ├── docs # 设计和用户文档(除了 godoc 生成的文档)。 ├── examples # 应用程序或公共库的示例程序。 ├── init # 系统初始化(systemd、upstart、sysv)和进程管理(runit、supervisord)配置。 ├── vendor # 若采用了vendor模式,则包含应用的所有依赖项 ├── .gitignore # 指定git忽略的非跟踪文件 ├── Dockerfile # 用于构建Docker镜像 ├── go.mod # 项目的模块依赖文件 ├── go.sum # 包含特定模块版本内容的预期校验和 └── README.md # 项目的说明文件,通常包含安装、构建、操作说明等
|
注意,这里的test目录通常用于外部测试的额外资料和数据。而项目本身的单元测试文件,通常与被测试文件放在同一个目录。
4. 小型项目布局说明
对于小型或者是短周期的项目,我们可能只需要以下几个组件:
1 2 3 4 5 6 7 8
| . ├── main.go # 如果是一个应用,这里是入口文件 ├── go.mod # 项目依赖文件 ├── go.sum # 依赖的校验和 ├── README.md # 项目说明文档 └── somepkg # 某些有意义的包 ├── file1.go └── file2.go
|
5. gin框架项目布局说明
对于gin框架,建议在【中大型项目布局说明】的基础上,增加几个包:
- internal/router
- internal/server
- internal/tools
示例项目:voidking/k8s-webhook
6. 后记
在所有情况下,确保代码易于理解、模块化和可测试非常重要,这样的项目结构更容易让新加入的开发者迅速上手和维护。
另外,随着项目的发展,结构可能需要根据新的需求进行调整,所以务必保持灵活性。