Original link: github.com/golang-stan…html
這是 Go 應用程序項目的基本佈局。它不是核心 Go 開發團隊定義的官方標準;然而,它是 Go 生態系統中一組常見的老項目和新項目的佈局模式。其中一些模式比其餘模式更受歡迎。它還具備許多小的加強,以及對任何足夠大的實際應用程序通用的幾個支持目錄。git
若是你嘗試學習 Go,或者你正在爲本身創建一個 PoC 或一個玩具項目,這個項目佈局是沒啥必要的。從一些很是簡單的事情開始(一個 main.go
文件綽綽有餘)。隨着項目的增加,請記住保持代碼結構良好很是重要,不然你最終會獲得一個凌亂的代碼,這其中就包含大量隱藏的依賴項和全局狀態。當有更多的人蔘與這個項目時,你將須要更多的結構。這時候,介紹一種管理包/庫的通用方法是很重要的。當你有一個開源項目時,或者當你知道其餘項目從你的項目存儲庫中導入代碼時,這時候擁有私有(又名 internal
)包和代碼就很重要。克隆存儲庫,保留你須要的內容,刪除其餘全部的內容!僅僅由於它在那裏並不意味着你必須所有使用它。這些模式都沒有在每一個項目中使用。甚至 vendor
模式也不是通用的。github
Go 1.14 Go Modules
終於能夠投入生產了。除非你有特定的理由不使用它們,不然使用 Go Modules
。若是你使用,就無需擔憂 $GOPATH 以及項目放置的位置。存儲庫中的 go.mod
文件基本假定你的項目託管在 Github 上,但這不是要求。模塊路徑能夠是任何地方,儘管第一個模塊路徑組件的名稱中應該有一個點(當前版本的 Go 再也不強制使用該模塊,但若是使用稍舊的版本,若是沒有 mod
文件構建失敗的話 ,不要驚訝)。若是你想知道更多信息,請參閱 Issues 37554
和 32819
。golang
此項目佈局是通用的,而且不會嘗試強加一個特定的 Go 包結構。web
這是社區的努力。 若是看到新的模式,或者認爲一個現有的模式須要更新,請提一個 issue。docker
若是須要命名、格式和樣式方面的幫助,請運行 gofmt
和 golint
。還要確保閱讀這些 Go 代碼風格的指導方針和建議:windows
參見 Go Project Layout
瞭解更多的背景信息。api
更多關於包的命名和組織以及其餘代碼結構的建議:安全
/cmd
本項目的主幹。服務器
每一個應用程序的目錄名應該與你想要的可執行文件的名稱相匹配(例如,/cmd/myapp
)。
不要在這個目錄中放置太多代碼。若是你認爲代碼能夠導入並在其餘項目中使用,那麼它應該位於 /pkg
目錄中。若是代碼不是可重用的,或者你不但願其餘人重用它,請將該代碼放到 /internal
目錄中。你會驚訝於別人會怎麼作,因此要明確你的意圖!
一般有一個小的 main
函數,從 /internal
和 /pkg
目錄導入和調用代碼,除此以外沒有別的東西。
有關示例,請參閱 /cmd
目錄。
/internal
私有應用程序和庫代碼。這是你不但願其餘人在其應用程序或庫中導入代碼。請注意,這個佈局模式是由 Go 編譯器自己執行的。有關更多細節,請參閱Go 1.4 release notes
。注意,你並不侷限於頂級 internal
目錄。在項目樹的任何級別上均可以有多個內部目錄。
你能夠選擇向 internal 包中添加一些額外的結構,以分隔共享和非共享的內部代碼。這不是必需的(特別是對於較小的項目),可是最好有有可視化的線索來顯示預期的包的用途。你的實際應用程序代碼能夠放在 /internal/app
目錄下(例如 /internal/app/myapp
),這些應用程序共享的代碼能夠放在 /internal/pkg
目錄下(例如 /internal/pkg/myprivlib
)。
/pkg
外部應用程序可使用的庫代碼(例如 /pkg/mypubliclib
)。其餘項目會導入這些庫,但願它們能正常工做,因此在這裏放東西以前要三思:-)注意,internal
目錄是確保私有包不可導入的更好方法,由於它是由 Go 強制執行的。/pkg
目錄仍然是一種很好的方式,能夠顯式地表示該目錄中的代碼對於其餘人來講是安全使用的好方法。由 Travis Jeffery 撰寫的 I'll take pkg over internal
博客文章提供了 pkg
和 internal
目錄的一個很好的概述,以及何時使用它們是有意義的。
當根目錄包含大量非 Go 組件和目錄時,這也是一種將 Go 代碼分組到一個位置的方法,這使得運行各類 Go 工具變得更加容易(正如在這些演講中提到的那樣: 來自 GopherCon EU 2018 的 Best Practices for Industrial Programming
, GopherCon 2018: Kat Zien - How Do You Structure Your Go Apps 和 GoLab 2018 - Massimiliano Pippi - Project layout patterns in Go )。
若是你想查看哪一個流行的 Go 存儲庫使用此項目佈局模式,請查看 /pkg
目錄。這是一種常見的佈局模式,但並非全部人都接受它,一些 Go 社區的人也不推薦它。
若是你的應用程序項目真的很小,而且額外的嵌套並不能增長多少價值(除非你真的想要:-),那就不要使用它。當它變得足夠大時,你的根目錄會變得很是繁瑣時(尤爲是當你有不少非 Go 應用組件時),請考慮一下。
/vendor
應用程序依賴項(手動管理或使用你喜歡的依賴項管理工具,如新的內置 Go Modules
功能)。go mod vendor
命令將爲你建立 /vendor
目錄。請注意,若是未使用默認狀況下處於啓用狀態的 Go 1.14,則可能須要在 go build
命令中添加 -mod=vendor
標誌。
若是你正在構建一個庫,那麼不要提交你的應用程序依賴項。
注意,自從 1.13
之後,Go 還啓用了模塊代理功能(默認使用 https://proxy.golang.org
做爲他們的模塊代理服務器)。在here
閱讀更多關於它的信息,看看它是否符合你的全部需求和約束。若是須要,那麼你根本不須要 vendor
目錄。
國內模塊代理功能默認是被牆的,七牛雲有維護專門的的模塊代理
。
/api
OpenAPI/Swagger 規範,JSON 模式文件,協議定義文件。
有關示例,請參見 /api
目錄。
/web
特定於 Web 應用程序的組件:靜態 Web 資產、服務器端模板和 SPAs。
/configs
配置文件模板或默認配置。
將你的 confd
或 consul-template
模板文件放在這裏。
/init
System init(systemd,upstart,sysv)和 process manager/supervisor(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
目錄中。請注意,有些 CI 工具(例如 Travis CI)對配置文件的位置很是挑剔。嘗試將配置文件放在 /build/ci
目錄中,將它們連接到 CI 工具指望它們的位置(若是可能的話)。
/deployments
IaaS、PaaS、系統和容器編排部署配置和模板(docker-compose、kubernetes/helm、mesos、terraform、bosh)。注意,在一些存儲庫中(特別是使用 kubernetes 部署的應用程序),這個目錄被稱爲 /deploy
。
/test
額外的外部測試應用程序和測試數據。你能夠隨時根據需求構造 /test
目錄。對於較大的項目,有一個數據子目錄是有意義的。例如,你可使用 /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 模式。你真的不但願你的 Go 代碼或 Go 項目看起來像 Java:-)
不要將項目級別 src
目錄與 Go 用於其工做空間的 src
目錄(如 How to Write Go Code
中所述)混淆。$GOPATH
環境變量指向你的(當前)工做空間(默認狀況下,它指向非 windows 系統上的 $HOME/go
)。這個工做空間包括頂層 /pkg
, /bin
和 /src
目錄。你的實際項目最終是 /src
下的一個子目錄,所以,若是你的項目中有 /src
目錄,那麼項目路徑將是這樣的: /some/path/to/workspace/src/your_project/src/your_code.go
。注意,在 Go 1.11 中,能夠將項目放在 GOPATH
以外,但這並不意味着使用這種佈局模式是一個好主意。
Go Report Card - It will scan your code with gofmt
, go vet
, gocyclo
, golint
, ineffassign
, license
and misspell
. Replace github.com/golang-standards/project-layout
with your project reference.
GoDoc - It will provide online version of your GoDoc generated documentation. Change the link to point to your project.
Release - It will show the latest release number for your project. Change the github link to point to your project.
A more opinionated project template with sample/reusable configs, scripts and code is a WIP.