Go Project Layout

這是 Go 應用程序項目的基本佈局。它不是核心 Go 開發團隊定義的官方標準;然而,它是 Go 生態系統中一組常見的老項目和新項目的佈局模式。其中一些模式比其他模式更受歡迎。它還具有許多小的增強,以及對任何足夠大的實際應用程序通用的幾個支持目錄。

如果你嘗試學習 Go,或者你正在爲自己建立一個 PoC 或一個玩具項目,這個項目佈局是沒啥必要的。從一些非常簡單的事情開始 (一個 main.go 文件綽綽有餘)。隨着項目的增長,請記住保持代碼結構良好非常重要,否則你最終會得到一個凌亂的代碼,這其中就包含大量隱藏的依賴項和全局狀態。當有更多的人蔘與這個項目時,你將需要更多的結構。這時候,介紹一種管理包 / 庫的通用方法是很重要的。當你有一個開源項目時,或者當你知道其他項目從你的項目存儲庫中導入代碼時,這時候擁有私有(又名 internal) 包和代碼就很重要。克隆存儲庫,保留你需要的內容,刪除其他所有的內容! 僅僅因爲它在那裏並不意味着你必須全部使用它。這些模式都沒有在每個項目中使用。甚至 vendor 模式也不是通用的。

Go 1.14 Go Modules 終於可以投入生產了。除非你有特定的理由不使用它們,否則使用 Go Modules 。如果你使用,就無需擔心 $GOPATH 以及項目放置的位置。存儲庫中的 go.mod 文件基本假定你的項目託管在 Github 上,但這不是要求。模塊路徑可以是任何地方,儘管第一個模塊路徑組件的名稱中應該有一個點(當前版本的 Go 不再強制使用該模塊,但如果使用稍舊的版本,如果沒有 mod 文件構建失敗的話 ,不要驚訝)。如果你想知道更多信息,請參閱 Issues 37554 和 32819 。

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

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

如果需要命名、格式和樣式方面的幫助,請運行 gofmt 和 golint 。還要確保閱讀這些 Go 代碼風格的指導方針和建議:

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

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

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 博客文章提供了 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 應用程序的組件: 靜態 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 之外,但這並不意味着使用這種佈局模式是一個好主意。

來源:

https://www.toutiao.com/article/7232164456753545768/?log_from=25c1b57d9ddd1_1684373307029

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/b0JIc7cQN-ctSkB6_grexQ