Go项目标准目录结构

是Go应用程序项目的基本布局。不是核心Go开发团队定义的官方标准;但是,这是Go生态系统中的一组常见的历史和新兴项目布局模式。其中一些模式比其他模式更受欢迎。它还具有许多小的增强功能,以及任何足够大的实际应用程序共有的几个支持目录。

如果您想学习Go,或者您自己构建PoC或玩具项目,则此项目布局实在是太过分了。从一个非常简单的事情开始(一个main.go文件绰绰有余)。随着项目的增长,请记住,确保您的代码结构合理非常重要,否则最终将导致混乱的代码具有很多隐藏的依赖关系和全局状态。当有更多的人从事项目时,您将需要更多的结构。在那时候,重要的是要引入一种管理软件包/库的通用方法。当您拥有一个开源项目时,或者当您知道其他项目从项目存储库中导入代码时,拥有私有(aka内部)包和代码就很重要。克隆存储库,保留您需要的内容,然后删除其他所有内容!仅仅因为它在那里并不意味着您必须全部使用它。这些模式均未在每个项目中使用。甚至供应商模式也不是通用的。

有了Go 1.14,Go模块终于可以投入生产了。除非您有特定的原因不使用Go Modules,否则请使用Go Modules;如果这样做,则无需担心$ GOPATH和项目放置位置。回购中的基本go.mod文件假定您的项目托管在Github上,但这不是必需的。模块路径可以是任何东西,尽管第一个模块路径组件的名称中应带有点(当前版本的Go不再强制使用该点,但是,如果您使用的是稍旧的版本,则在构建失败时不会感到惊讶)它)。如果您想了解更多信息,请参见问题37554和32819。

该项目布局是有意通用的,并且不会尝试施加特定的Go包结构。

这是社区的努力。如果看到新的模式,或者认为需要更新现有模式之一,则打开一个问题。

如果需要命名,格式和样式方面的帮助,请先运行gofmt和golint。另外,请务必阅读以下Go代码样式指南和建议:

有关其他背景信息,请参见转到项目布局。

有关命名和组织软件包以及其他代码结构建议的更多信息:

Go 目录

/cmd

该项目的主要应用。

每个应用程序的目录名称应与您想要的可执行文件的名称匹配(例如,“ / cmd / myapp”)。

不要在应用程序目录中放置过多代码。 如果您认为该代码可以导入并在其他项目中使用,那么它应该位于/ pkg目录中。 如果该代码不可重用,或者您不希望其他人重用它,则将该代码放在/ internal目录中。 您会惊讶于其他人会做什么,因此要明确您的意图!

通常有一个小的main函数可以从/ internal和/ pkg目录中导入并调用代码,而没有别的。

查看 /cmd 目录获取更多示例。

/internal

私有应用程序和库代码。 这是您不希望其他人在其应用程序或库中导入的代码。 请注意,此布局模式由Go编译器本身强制执行。 有关更多详细信息,请参见Go 1.4发行说明。 请注意,您不限于顶层内部目录。 在项目树的任何级别上,您都可以具有多个内部目录。

您可以选择向内部软件包中添加一些额外的结构,以分隔共享和非共享内部代码。 它不是必需的(尤其是对于较小的项目),但是最好有视觉提示来显示包装的预期用途。 您的实际应用程序代码可以放在/ internal / app目录(例如/ internal / app / myapp)中,而这些应用程序共享的代码可以在/ internal / pkg目录中(例如/ internal / pkg / myprivlib)。

/pkg

外部应用程序可以使用的库代码(例如/ pkg / mypubliclib)。 其他项目将导入这些库,希望它们能正常工作,因此在将某些内容放到这里之前,请三思:-)注意,内部目录是确保您的私有软件包不可导入的更好方法,因为它由Go强制执行。 / pkg目录仍然是明确传达该目录中的代码可被他人安全使用的好方法。 Travis Jeffery撰写的关于内部博客的pkg文章将很好地概述了pkg和内部目录以及何时使用它们。

当您的根目录包含大量非Go组件和目录时,这也是一种将Go代码分组到一个位置的方法,这使得运行各种Go工具变得更加容易(如在这些演讲中提到的那样:GopherCon EU 2018的工业编程最佳实践)GopherCon 2018: Kat Zien - How Do You Structure Your Go Apps and GoLab 2018 - Massimiliano Pippi - Project layout patterns in Go).

如果要查看哪个流行的Go存储库使用此项目布局模式,请参见/ pkg目录。 这是一种常见的布局模式,但未被普遍接受,并且Go社区中的某些人不推荐这样做。

如果您的应用程序项目很小,并且嵌套的额外层次不会增加太多价值(除非您真的想要:-),请不要使用它。 当它变得足够大并且您的根目录变得非常繁忙时(特别是如果您有很多非Go应用程序组件),请考虑一下。

/vendor

应用程序依赖项(手动或通过您喜欢的依赖项管理工具(如新的内置Go模块功能)进行管理)。 go mod vendor命令将为您创建/ vendor目录。 请注意,如果您不使用默认情况下处于启用状态的Go 1.14,则可能需要在go build命令中添加-mod = vendor标志。

如果要构建库,请不要提交应用程序依赖项。

请注意,自1.13开始,Go还启用了模块代理功能(默认情况下使用https://proxy.golang.org作为其模块代理服务器)。 在此处阅读有关它的更多信息,以了解它是否符合您的所有要求和约束。 如果是这样,那么您根本不需要供应商目录。

服务应用程序目录

/api

OpenAPI / Swagger规范,JSON模式文件,协议定义文件。

有关示例,请参见/ api目录。

Web 应用程序目录

/web

Web应用程序特定的组件:静态Web资产,服务器端模板和SPA。

通用应用程序目录

/configs

配置文件模板或默认配置。

将您的confdconsul-template模板文件放在此处。

/init

系统初始化(systemd,upstart,sysv)和进程管理器/主管(runit,supervisor)配置。

/scripts

用于执行各种构建,安装,分析等操作的脚本。

这些脚本使根级别的Makefile变得小而简单(例如https://github.com/hashicorp/terraform/blob/master/Makefile)。

有关示例,请参见/ scripts目录。

/build

包装和持续集成。

将您的云(AMI),容器(Docker),操作系统(deb,rpm,pkg)软件包配置和脚本放在/ build / package目录中。

将您的CI(travis,circle,drone)配置和脚本放在/ build / ci目录中。 请注意,某些配置项工具(例如Travis CI)对于其配置文件的位置非常挑剔。 尝试将配置文件放在/ build / ci目录中,将它们链接到CI工具期望它们的位置(如果可能)。

/deployments

IaaS,PaaS,系统和容器编排部署配置和模板(docker-compose,kubernetes / helm,mesos,terraform,bosh)。 请注意,在某些存储库中(尤其是使用kubernetes部署的应用程序),该目录称为/ deploy。

/test

其他外部测试应用程序和测试数据。 随时根据需要构建/ test目录。 对于较大的项目,有一个数据子目录是有意义的。 例如,如果需要Go来忽略该目录中的内容,则可以使用/ test / data或/ test / testdata。 请注意,Go还将忽略以“。”开头的目录或文件。 或“ _”,因此您在命名测试数据目录的方式上更具灵活性。

有关示例,请参见/ test目录。

其他目录

/docs

设计和用户文档(除了godoc生成的文档之外)。

有关示例,请参见/ docs目录。

/tools

此项目的支持工具。 请注意,这些工具可以从/ pkg和/ internal目录导入代码。

有关示例,请参见/ tools目录。

/examples

您的应用程序和/或公共库的示例。

有关示例,请参见/ examples目录。

/third_party

外部帮助程序工具,分叉的代码和其他第三方工具(例如Swagger UI)。

/githooks

Git hooks.

/assets

与资源库一起使用的其他资产(图像,徽标等)。

/website

如果您不使用Github页面,则在这里放置项目的网站数据。

有关示例,请参见/ website目录。

您不应该拥有的目录

src

有些Go项目确实有一个src文件夹,但通常是在开发人员来自Java世界(通常是Java模式)时发生的。 如果可以帮助自己,请尝试不要采用此Java模式。 您真的不希望您的Go代码或Go项目看起来像Java :-)

不要将项目级别的/ src目录与Go用于其工作区的/ src目录混淆,如如何编写Go代码中所述。 $ GOPATH环境变量指向您(当前)的工作空间(默认情况下,它指向非Windows系统上的$ HOME / go)。 此工作空间包括顶级/ pkg,/ bin和/ src目录。 实际的项目最终是/ src下的子目录,因此,如果项目中有/ src目录,则项目路径将如下所示:/ some / path / to / workspace / src / your_project / src / your_code。 走。 请注意,使用Go 1.11,可以将项目放在GOPATH之外,但这并不意味着使用此布局模式是个好主意。

参考文档:

golang-standards

updatedupdated2020-05-102020-05-10
Load Comments?