Go Module 教程:Vendoring

作者是一個 Vendoring 愛好者。覺得它合理和實用,可以用於你的應用程序項目。

引言

我相信 Vendoring 給你的應用程序項目最持久的穩定保證,因爲該項目擁有每一行源代碼,它需要構建應用程序。如果你想要一個可重複的構建,而不需要依賴外部服務(比如模塊鏡像),並且不需要連接到網絡,那麼 vendoring 就是解決方案。

Vendoring 的其他好處有:

在這篇文章中,我將提供 Go 支持 Vendoring 的歷史,以及隨着時間的推移默認行爲的改變。我還將分享 Go 的工具如何能夠維護版本間的向後兼容性。最後,我將分享可能需要 (隨着時間的推移) 手動升級 go.mod 文件中列出的版本,以更改未來 Go 版本的默認行爲。

本文是 Go 語言中文網組織的 GCTT 翻譯,發佈在 Go 語言中文網公衆號,轉載請聯繫我們授權。

運行不同版本的 Go

爲了向你展示 Go 1.13 和 Go 1.14 之間默認行爲的差異,我需要能夠同時在我的機器上運行這兩個版本的工具。在我發表這篇文章的時候,我已經在我的機器上安裝了 Go 1.14.2,我使用傳統的 go 訪問這個版本。但是對於這篇文章,我還需要運行一個 Go 1.13 環境。那麼,如何才能在不破壞我目前的開發環境的情況下做到這一點呢?

關於這點,「polarisxu」公衆號發表兩篇相關的文章:

推薦大家參考使用。

Vendoring 快速參考

Go 工具在管理和 vendor 應用程序項目的依賴關係方面做了很好的工作,最小化了對工作流的影響。它有兩個子命令:tidyvendor

go mod tidy 命令可以保證項目的依賴準確的列出。有些編輯器 (比如 VS Code 和 GoLand) 提供了在開發期間更新模塊文件的功能,但這並不意味着一旦一切正常工作,模塊文件就會變得乾淨和準確。我建議在提交代碼之前運行 go mod tidy 命令,並將代碼 push 到 VCS。

如果你也想 vendor 這些依賴項,那麼在 tidy 之後運行 vendor 命令。

go mod vendor

此命令在項目中創建一個 vendor 文件夾,其中包含項目構建和測試代碼所需的所有依賴項 (直接和間接) 的源代碼。在運行 tidy 之後應該運行此命令,以保持 vendor 文件夾與模塊文件同步。確保提交併將 vendor 文件夾推送到 VCS。

版本間的向後兼容性

在 Go 1.14 中,在模塊緩存上默認使用 vendor 文件夾的更改是我希望項目的行爲。起初我以爲我可以用 Go 1.14 來構建我現有的項目,這就足夠了,但是我錯了。在我第一次使用 Go 1.14 構建並且沒有看到 vendor 文件夾後,我瞭解到 Go 工具讀取 go.mod 文件以獲取版本信息,並且保持與列出的版本的向後兼容性。其實在 Go 1.14 的發佈說明中清楚地表達了這一點。https://golang.org/doc/go1.14#go-command。

當主模塊包含頂級 vendor 目錄並且它的 go.mod 文件指定 Go 1.14 或更高時,Go 命令現在默認爲 -mod=vendor 來執行接受該標誌的操作。

爲了使用新的默認 vendoring 行爲,我需要將 go.mod 文件中的版本信息從 Go 1.13 升級到 Go 1.14。

GOPATH 或 Module 模式

在 Go 1.11 中,向 Go 工具添加了一個新的模式,稱爲 “模塊模式”。當 Go 工具以模塊模式運行時,模塊系統用於查找和生成代碼。當 Go 工具以 GOPATH 模式運行時,傳統的 GOPATH 系統將繼續用於查找和構建代碼。我在使用 Go 工具時遇到的一個更大的問題是,知道不同版本之間默認使用什麼模式。然後知道哪些配置更改和標誌需要保持構建的一致性。

爲了理解 Go 過去 4 個版本的歷史和語義變化,最好重溫一下這些模式。(截止 2021 年 9 月,已經發布了 Go1.17)

Go 1.11

引入了一個叫做 GO111MODULE 的新環境變量,它的默認設置是 auto。這個變量將決定 Go 工具是使用模塊模式還是 GOPATH 模式,具體取決於代碼所在的位置 (GOPATH 內部或外部)。若要強制一種模式或另一種模式,您可以將此變量設置爲 on 或 off。當涉及到 vendor 文件夾時,模塊模式將默認忽略 vendor 文件夾,並建立對模塊緩存的依賴關係。

Go 1.12

GO111MODULE 的默認設置仍然是 auto,Go 工具繼續根據代碼所在的位置 (GOPATH 內部或外部) 確定模塊模式或 GOPATH 模式。對於 vendor 文件夾,模塊模式在默認情況下仍然會忽略 vendor 文件夾,並依賴於模塊緩存。

Go 1.13

GO111MODULE 的默認設置仍然是 auto,但是 Go 工具不再對工作目錄是否在 GOPATH 中敏感。模塊模式在默認情況下仍然會忽略 vendor 文件夾,並依賴模塊緩存生成依賴項。

Go 1.14

GO111MODULE 的默認設置仍然是 auto,Go 工具不再對 GOPATH 中是否包含工作目錄敏感。但是,如果存在 vendor 文件夾,默認情況下將使用它來構建依賴項,而不是構建模塊緩存。此外,go 命令驗證項目的 vendor/modules.txt 文件與它的 go.mod 文件是否一致。

從 Go1.16 起,GO111MODULE  默認值設置爲 on,即默認啓用 Module 模式。

總結

不知道大家用 Vendor 多不多?如果依賴很多,Vendor 似乎是比較好的選擇。像 Kubernetes 使用的就是 Vendor。

本文只是簡單的介紹了 Vendoring,畢竟使用很簡單,可以根據你的情況來決定。

沒有完全按照文章翻譯。


via: https://www.ardanlabs.com/blog/2020/04/modules-06-vendoring.html

作者:William Kennedy[1] 譯者:polaris1119[2] 校對:polaris1119[3]

本文由 GCTT[4] 原創編譯,Go 中文網 [5] 榮譽推出,發佈在 Go 語言中文網公衆號,轉載請聯繫我們授權。

參考資料

[1]

William Kennedy: https://www.ardanlabs.com/

[2]

polaris1119: https://github.com/polaris1119

[3]

polaris1119: https://github.com/polaris1119

[4]

GCTT: https://github.com/studygolang/GCTT

[5]

Go 中文網: https://studygolang.com/

福利

我爲大家整理了一份從入門到進階的 Go 學習資料禮包,包含學習建議:入門看什麼,進階看什麼。關注公衆號 「polarisxu」,回覆 ebook 獲取;還可以回覆「進羣」,和數萬 Gopher 交流學習。

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