【必看】標準的 Go 項目佈局

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 3755432819golang

此項目佈局是通用的,而且不會嘗試強加一個特定的 Go 包結構。web

這是社區的努力。 若是看到新的模式,或者認爲一個現有的模式須要更新,請提一個 issue。docker

若是須要命名、格式和樣式方面的幫助,請運行 gofmtgolint 。還要確保閱讀這些 Go 代碼風格的指導方針和建議:windows

參見 Go Project Layout 瞭解更多的背景信息。api

更多關於包的命名和組織以及其餘代碼結構的建議:安全

Go 目錄

/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 博客文章提供了 pkginternal 目錄的一個很好的概述,以及何時使用它們是有意義的。

當根目錄包含大量非 Go 組件和目錄時,這也是一種將 Go 代碼分組到一個位置的方法,這使得運行各類 Go 工具變得更加容易(正如在這些演講中提到的那樣: 來自 GopherCon EU 2018 的 Best Practices for Industrial Programming , GopherCon 2018: Kat Zien - How Do You Structure Your Go AppsGoLab 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 應用程序的組件:靜態 Web 資產、服務器端模板和 SPAs。

通用應用目錄

/configs

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

將你的 confdconsul-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 以外,但這並不意味着使用這種佈局模式是一個好主意。

Badges

  • 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.

Go Report Card Go Doc Release

Notes

A more opinionated project template with sample/reusable configs, scripts and code is a WIP.

相關文章
相關標籤/搜索