如何优雅的组织Golang项目结构

一个Go项目的结构设计始终遵循Go语言的简洁高效理念 。一个合理和良好的布局可以提高代码的可读性 , 简化依赖管理,并优化编译过程 。
像cmd、internal和docs这样的目录是标准Go项目的基?。?起着不同的作用 。比如,cmd目录是可执行文件的入口 , docs是所有相关文档的入口,而internal包含项目私有代码 。适当的包划分可以避免循环依赖,便于单元测试和代码复用 。
然而,这种Go项目布局可能导致过多的目录层级和包划分,会给管理工作带来负担,并有时让初学者感到不知所措 。
因此,在设计时如何把握什么算是“合理”,就成了关键 。
这篇文章,让我们尝试在目录结构和包设计中找到简洁和功能之间的平衡,使项目能够在变化中健康迭代 。
标准布局像cmd和internal这样的目录结构是由一些Go语言社区的开发者在系统总结之前进行了总结 , 并在标准Go项目布局中得到了进一步的概括,该项目已经获得了超过4万个star 。尽管其起源是一个提示,但标准布局已经成为Go项目目录结构的事实标准 。
这并不是由核心Go开发团队定义的官方标准 。
my-App/ # Root directory of the project|── cmd/ # Executables directory└── myapp/ # MAIn application package└── main.go # Main application entry point|── internal/ # Private application and library code└── package1/ # Internal package 1|── pkg/ # Library code that can be exported└── package2/ # External package 2|── api/ # API protocol definitions directory|── configs/ # Configuration files directory|── deployments/ # Deployment configurations and scripts|── scripts/ # Scripts for build, install, analysis, etc.|── build/ # Packaging and Continuous Integration|── tests/ # Additional external test apps and test data|── docs/ # Design and user documents|── tools/ # Supporting tools for the project|── examples/ # Application or public library examples|── third_party/ # External helper tools, forked code, and other 3rd party utilities|── githooks/ # Git hooks|── assets/ # Other assets like images, logos, etc.|── vendor/ # Dependency package directory (if using vendor mode)|── go.mod # Module dependency file|── go.sum # Module checksum file for dependency verification如果你经常阅读源代码,你会轻易地发现,大多数在Github上知名的Go开源项目基本上都遵循上述布局,比如Kube.NETes这个大型Go项目 。

如何优雅的组织Golang项目结构

文章插图
让我们简单看一下 。
  • 与Go模块相关的go.mod和go.sum是必不可少的 。
  • pkg目录包含api、apis、kubectl等包,可应用于外部项目,比如基于Kubernetes的开发 。
  • cmd包含了Kubernetes中各种命令行的main方法入口,比如kubectl.go 。
  • api目录存储与openApiv3相关的json文件 。
  • test目录包含所有的e2e和集成测试代码,根据不同的包进行了分别存储 。
  • third_party存储第三方引用的工具,比如protobuf 。
  • vendor用于存储外部依赖 , 比如k8s.io、etcd等 。
  • docs目录目前为空 。
当然,Kubernetes项目并不完全遵循标准布局,因为其规模较大 。例如,许多Kubernetes脚本存储在build和cluster目录中 , 而不是scripts目录 。还有一些用于特定需求的目录,比如hacks和staging 。
官方布局2023年发布的文章《组织Go模块》揭示了Go团队对布局的不同观点,提供了根据项目复杂性设计目录结构的参考,涵盖了具有少量Go文件、单个cmd命令或简单包的项目,以及具有多个cmds和多个包的项目 。
对它们进行总结如下,并将其作为下一节的官方布局 。
my-module/# Root directory for the module with go.mod├── go.mod# Module's dependency file├── go.sum# The module's checksums for dependency validation├── cmd/# Directory for commands (each subdirectory here is a main package)│└── my-app/# Main application for this module│└── main.go# Main application entry point├── internal/# Internal packages meant for use only within this module│└── mylib/# An internal package example│└── mylib.go# The package's specific code├── api/# API protocol definitions, e.g., protocol buffer files├── web/# Web application specific components: static files, server-side templates, SPAs, etc.├── pkg/# Library code that's ok to use by external applications (deprecated by some in the community)│└── mypkg/# An example package that could be imported by other applications│└── mypkg.go# Package code├── README.md# Project README file├── LICENSE# License file├── .gitignore# Specifies intentionally untracked files to ignore└── ...<-- Other directories and files as needed


推荐阅读