① go進階1-go mod使用入門
最近在梳理項目,排查隱患。有個go的核心項目一直使用的最傳統的go path方式管理方式。是手動管理依賴的。這樣不太合理。
首先vendor太大了,129M。其次,更重要的是依賴包沒有版本控制,之前一直是我一個人在開發,後續如果多人開發就是個隱患。現計劃升級成 go mod包管理。這里把涉及的知識點做一下匯總。
go moles 是 golang 1.11 新加的特性。moles的官方定義如下:
現在的方式是將開源的最新代碼通過 go get 下載到本地的GOPATH 目錄,然後需要時就去對應的 GOPATH 目錄去查找了。這就不可避免帶來一個問題,開源庫總會升級,不同時間點下載的代碼可能不一樣。每次升級都要刪除後重新引用,也增加了運維成本。
而go mod管理只需要一個go.mod文件即可。它通過在 go.mod 這個文件里記錄了當前項目里所有依賴包的 git 倉庫地址以及對應的版本號,來解決了包依賴管理的問題,後續在構建編譯時,就會根據對應的版本號去拉取依賴包。也就是說只要我們維護了 gomod 文件,依賴問題就不再是問題了。
GO111MODULE 參數
GO111MODULE 有三個值:off, on和auto(默認值)
GO111MODULE=off,go命令行將不會支持mole功能,尋找依賴包的方式將會沿用舊版本那種通過vendor目錄或者GOPATH模式來查找。
GO111MODULE=on,go命令行會使用moles,而一點也不會去GOPATH目錄下查找。
GO111MODULE=auto,默認值,go命令行將會根據當前目錄來決定是否啟用mole功能。如果有 go.mod 文件就啟用。
下面設置go mod和go proxy
配置完如下
初始化 go.mod 文件
查看 go.mod 內容如下
現在把這個 mole 發布到github上,然後在別的項目中引用
在github上創建一個空倉庫
項目上傳到上述倉庫(假設你已經完成本地ssh key到github)
執行完上面,相當於發布完成了。後續有人想用就可以直接 require 。
但這時候還沒有加tag,所以沒有版本管理。使用 tag 進行版本控制。
操作完,我們的mole就發布了一個v1.0.0的版本了。
tag是點,不可移動。branch是由點組成的線。後續可以基於某tag標簽 checkout 一個版本,進行修改。不要在master上修改。
主項目引用遠程mole
代碼寫好了,生成 go.mod 文件。
查看 go.mod
接下來就是享受 go.mod 便利的時候。一鍵操作。
1),將引用的開源包下載到 GOPSTH/pkg/mod 目錄
2),同時生成了 gp.sum 。
go.mod: 可以理解為包管理文件。
go.sum: 可以理解為包的版本控制文件。更准確地來說,go.sum是一個構建狀態跟蹤文件。
接下來可以直接運行了。
假如fix一個bug,我們在v1.0.0 版本上進行修復。如 [email protected] => [email protected] 。更新引用包的版本:
修改 go.mod ,然後再次 go mod tidy 即可。會自動下載對應版本的開源包。非常方便。
上述就是go mod 的完整使用過程。go mod init、go mod tidy,基本就能解決很多依賴問題了。這也是 Go 官方一直提倡的簡潔、優雅。
② 《快學 Go 語言》第 16 課 —— 包管理 GOPATH 和 Vendor
學習 Go 語言的模塊管理功能,從 GOPATH 和 Vendor 機制開始。隨著 Go 語言的發展,模塊管理經歷了三個階段,分別是通過全局的 GOPATH 管理第三方包、通過 Vendor 機制將依賴包局部化,以及最新的 Go Mole 功能。
在模塊管理的初期階段,Go 語言使用全局的 GOPATH 路徑來存放所有第三方依賴包。編譯器在尋找包對象時,會優先檢查 GOPATH 路徑下的文件。通常,用戶會將 GOPATH 設置為 ~/go 目錄。了解三個關鍵子目錄:src、pkg 和 bin,分別存放源代碼、編譯好的包對象和二進制可執行文件。
全局管理的 GOPATH 允許通過網站域名編寫友好的包路徑,使用 go get 指令從 GitHub、gopkg.in 和 golang.org 等網站拉取代碼。此外,Go 語言提供了標準的模塊結構,用戶可以參照現有項目來構建自己的模塊。
編寫第一個模塊時,需要在 GOPATH 中創建相應的目錄結構,並編寫代碼。使用 go get 將模塊提交至 GitHub。通過 go run 命令測試模塊功能,然後使用 go get 更新模塊至 GitHub。值得注意的是,Go 語言不推薦使用相對導入,通常建議採用絕對導入。
若遇到兩個包路徑的結尾相同,Go 語言支持導入語句名稱替換功能來區分。此外,Go 還支持無名導入和匿名導入,但這些用法較少見且不建議使用。
Go 提供了三個指令來管理全局包:go build、go install 和 go get。go build 僅編譯代碼,go install 編譯後安裝包,而 go get 下載並編譯包。在開發過程中,先執行 go build -i 可以加快運行速度。
為了解決不同項目依賴不同版本的第三方包問題,引入了 Vendor 機制。Vendor 目錄將項目依賴的第三方包進行本地化管理,優先在 Vendor 中查找所需包。每個項目都有一個 Vendor 子目錄,形成依賴樹,但實際依賴深度通常較小。使用 Vendor 的限制是不能將依賴暴露到外部,以實現項目間版本隔離。
當需要引入具體版本的第三方包時,可以使用 Go 的依賴管理工具 Dep。Dep 管理項目配置文件 Godep.toml 和 Godep.lock,用於指定依賴規則和版本。初始化項目後,使用 dep ensure 指令確保依賴項與項目配置一致。更新版本或添加新依賴時,可執行相關 dep 命令。
盡管 Dep 工具復雜但使用簡單,它支持下載新依賴、移除不使用的依賴,並確保依賴與配置文件完全匹配。Dep 雖然在 Go 社區中流行,但最終 Go 語言官方推薦使用 Go Mole 作為替代方案。