这是Go应用程序项目的基本布局。它不是核心Go开发团队定义的官方标准; 然而,它是Go生态系统中一组常见的历史和新兴项目布局模式。其中一些模式比其他模式更受欢迎。它还有许多小的增强功能以及任何足够大的真实世界应用程序共有的几个支持目录。
如果您正在尝试学习Go或者您正在为自己构建PoC或玩具项目,那么这个项目布局是一种过度杀伤力。从一些非常简单的东西开始(单个main.go
文件绰绰有余)。随着项目的增长,请记住,确保您的代码结构良好非常重要,否则您最终会得到一个包含大量隐藏依赖项和全局状态的混乱代码。当你有更多的人在项目上工作时,你需要更多的结构。那时候介绍管理包/库的常用方法很重要。当你有一个开源项目或者当你知道其他项目从你的项目存储库中导入代码时,那就是私有(也就是说私有的)internal
)包和代码。克隆存储库,保留所需内容并删除其他所有内容!只是因为它在那里并不意味着你必须全部使用它。在每个项目中都没有使用这些模式。即使这种vendor
模式也不普遍。
此项目布局是有意通用的,它不会尝试强加特定的Go包结构。
这是社区的努力。如果您看到新模式或者您认为某个现有模式需要更新,请打开一个问题。
如果你需要帮助命名,格式化和样式开始运行gofmt
和golint
。另外,请务必阅读这些Go代码样式指南和建议:
有关Go Project Layout
其他背景信息,请参阅
有关命名和组织包以及其他代码结构建议的更多信息:
/cmd
该项目的主要应用。
每个应用程序的目录名称应与您想要的可执行文件的名称相匹配(例如/cmd/myapp
)。
不要在应用程序目录中放入大量代码。如果您认为代码可以导入并在其他项目中使用,那么它应该存在于/pkg
目录中。如果代码不可重用或者您不希望其他人重用它,请将该代码放在/internal
目录中。你会惊讶于别人会做什么,所以要明确你的意图!
通常有一个小main
函数可以从/internal
和/pkg
目录中导入和调用代码,而不是其他任何东西。
请参阅/cmd
目录以获取示例。
/internal
私有应用程序和库代码。这是您不希望其他人在其应用程序或库中导入的代码。
将您的实际应用程序代码放在/internal/app
目录(例如/internal/app/myapp
)和/internal/pkg
目录中这些应用程序共享的代码(例如/internal/pkg/myprivlib
)。
/pkg
可以由外部应用程序使用的库代码(例如/pkg/mypubliclib
)。其他项目将导入这些库,期望它们可以工作,所以在你把东西放在这里之前要三思而后行:-)
当你的根目录包含许多非Go组件和目录时,它也可以在一个地方将Go代码分组,从而更容易运行各种Go工具(如Best Practices for Industrial Programming
GopherCon EU 2018中所述)。
/pkg
如果您想查看哪个热门的Go repos使用此项目布局模式,请查看该目录。这是一种常见的布局模式,但它并未被普遍接受,Go社区中的一些人不推荐它。
/vendor
应用程序依赖项(手动管理或由您喜欢的依赖管理工具管理dep
)。
如果要构建库,请不要提交应用程序依赖项。
/api
OpenAPI / Swagger规范,JSON模式文件,协议定义文件。
请参阅/api
目录以获取示例。
/web
特定于Web应用程序的组件:静态Web资产,服务器端模板和SPA。
/configs
配置文件模板或默认配置。
将您的confd
或consul-template
模板文件放在这里。
/init
系统初始化(systemd,upstart,sysv)和进程管理器/主管(runit,supervisord)配置。
/scripts
脚本执行各种构建,安装,分析等操作。
这些脚本使根级Makefile保持简洁(例如https://github.com/hashicorp/terraform/blob/master/Makefile
)。
请参阅/scripts
目录以获取示例。
/build
包装和持续集成。
将您的云(AMI),容器(Docker),OS(deb,rpm,pkg)包配置和脚本放在/build/package
目录中。
将CI(travis,circle,drone)配置和脚本放在/build/ci
目录中。请注意,某些CI工具(例如,Travis CI)对其配置文件的位置非常挑剔。尝试将配置文件放在/build/ci
将它们链接到CI工具所期望的位置的目录中(如果可能)。
/deployments
IaaS,PaaS,系统和容器编排部署配置和模板(docker-compose,kubernetes / helm,mesos,terraform,bosh)。
/test
其他外部测试应用和测试数据。您可以随意构建/test
目录。对于更大的项目,有一个数据子目录是有意义的。例如,您可以拥有/test/data
或者/test/testdata
如果需要Go来忽略该目录中的内容。请注意,Go也会忽略以“。”开头的目录或文件。或“_”,因此您在命名测试数据目录方面具有更大的灵活性。
请参阅/test
目录以获取示例。
/docs
设计和用户文档(除了你的godoc生成的文档)。
请参阅/docs
目录以获取示例。
/tools
该项目的支持工具。请注意,这些工具可以从/pkg
和/internal
目录中导入代码。
请参阅/tools
目录以获取示例。
/examples
应用程序和/或公共库的示例。
请参阅/examples
目录以获取示例。
/third_party
外部帮助工具,分叉代码和其他第三方实用程序(例如,Swagger UI)。
/githooks
Git钩子。
/assets
与您的存储库一起使用的其他资产(图像,徽标等)。
/website
如果您不使用Github页面,这是放置项目的网站数据的地方。
请参阅/website
目录以获取示例。
/src
一些Go项目确实有一个src
文件夹,但它通常发生在开发人员来自Java世界时,它是一种常见的模式。如果您可以帮助自己尝试不采用此Java模式。你真的不希望你的Go代码或Go项目看起来像Java :-)
不要将项目级/src
目录与/src
Go用于其工作空间的目录混淆,如中所述How to Write Go Code
。在$GOPATH
您(电流)工作区环境变量指向(默认情况下它指向$HOME/go
上的非Windows系统)。这个工作区包含顶层/pkg
,/bin
和/src
目录。您的实际项目最终成为一个子目录/src
,因此如果/src
项目中有目录,项目路径将如下所示:/some/path/to/workspace/src/your_project/src/your_code.go
。请注意,使用Go 1.11可以将项目置于您的项目之外GOPATH
,但这并不意味着使用此布局模式是个好主意。