3.4 Go語言從入門到精通:包管理工具之Go module
作者:xcbeyond
瘋狂源自夢想,技術成就輝煌!微信公眾號:《程序猿技術大咖》號主,專注后端開發(fā)多年,擁有豐富的研發(fā)經驗,樂于技術輸出、分享,現(xiàn)階段從事微服務架構項目的研發(fā)工作,涉及架構設計、技術選型、業(yè)務研發(fā)等工作。對于Java、微服務、數(shù)據(jù)庫、Docker有深入了解,并有大量的調優(yōu)經驗。
Go modules 是 Go 語言目前最佳的依賴解決方案,發(fā)布于 Go 1.11版本,Go1.14版本 上已經明確建議生產上使用。而
Go modules 之前,Go 項目使用 GOPATH
、Govendor包管理方式,但卻都存在一定的問題,本文就重點討論關于另外一個包管理工具 Go module 的由來及使用。
1、Go module 概述
1.1 Go module介紹
使用 GOPATH 包管理方式,最嚴重的問題就是當使用go get 命令時,沒有版本選擇機制,拉取下來的依賴代碼都會默認當前最新版本,而且如果當項目 A 和項目 B 分別依賴項目 C 的兩個不兼容版本時, GOPATH 路徑下只有一個版本,則 C 將無法同時滿足 A 和 B 的依賴需求。這可以說是一個很大的缺陷了,因而 Go 1.13版本 起,官方就不再推薦使用 GOPATH 方式了。
隨著 Go 語言使用人數(shù)的增長,依賴包的豐富,依賴版本問題尤其嚴重。
于是 Go 官方在 Go 1.5版本的時候提出了實驗性質的 vendor 機制:每個項目都可以有一個vendor/ 目錄來存放項目所需版本依賴的拷貝。
社區(qū)中基于官方給的機制,開發(fā)出了各種版本管理工具。比較流行的比如 govendor,以及之前曾被官方認定的 godep 工具等。
這些工具的思路基本都是為每個項目單獨維護一份對應版本依賴的拷貝。
管理工具雖然豐富了起來,但是不同版本工具之間不兼容,無法協(xié)作,各種工具還都有學習成本。這時候在 Go 官方扶持下成立的 dep 項目被大家認為是未來一統(tǒng)江湖的版本管理工具,被稱作 official experiment。
dep 采用了和 Rust 的管理工具 Cargo 類似的管理模式,原理在此不深究。
沒過多久,Go 社區(qū)的核心人物 rsc 提出了 vgo 方案。一時間竟然出現(xiàn)了兩個所謂的 Go 官方的版本管理方案。最終官方采用了 vgo 方案,隨著 vgo 的逐漸成熟,Go 1.11版本發(fā)布了該功能,并集成到了 Go 的官方工具中,也就是當前的 Go modules。
Go module 是Go語言從 1.11 版本之后官方推出的版本管理工具,并且從 Go 1.13 版本開始,Go module 成為了Go 語言默認的依賴管理工具。
Modules 官方定義為:
Modules 是相關 Go 包的集合,是源代碼交換和版本控制的單元。Go 語言命令直接支持使用 Modules,包括記錄和解析對其他模塊的依賴性,Modules 替換舊的基于 GOPATH 的方法,來指定使用哪些源文件。
1.2 Go module 常用命令
2、快速入門
2.1 設置環(huán)境變量
要使用 Go module 必須確保 Go 版本在1.11之上。
設置 GO111MODULE
在Go 1.12 版本之前,要啟用 go module 工具首先要設置環(huán)境變量 GO111MODULE,不過在Go 1.13及以后的版本,則不再需要設置環(huán)境變量。通過 GO111MODULE 可以開啟或關閉 go module 工具。
GO111MODULE=off 禁用 go module,編譯時會從 GOPATH 和 vendor 文件夾中查找包。
GO111MODULE=on 啟用 go module,編譯時會忽略 GOPATH 和 vendor 文件夾,只根據(jù) go.mod下載依賴。
GO111MODULE=auto(默認值),當項目在 GOPATH/src 目錄之外,并且項目根目錄有 go.mod 文件時,開啟 go module。
Window:
set GO111MODULE=on
// 或者
set GO111MODULE=auto
MacOS 或 Linux:
export GO111MODULE=on
// 或者
export GO111MODULE=auto
2.2 項目初始化
在 GOPATH 目錄之外新建一個目錄,并使用 go mod init 初始化生成 go.mod 文件。
E:\github\golangLearning>go mod init golangLearning
go: creating new go.mod: module golangLearning
go: to add module requirements and sums:
go mod tidy
初始化生成的 go.mod 文件如下所示:
module golangLearning
go 1.16
2.3 添加依賴
新建一個 main.go 文件,代碼如下:
package main
import (
“net/http”
“github.com/labstack/echo”
)
func main() {
e := echo.New()
e.GET("/", func(c echo.Context) error {
return c.String(http.StatusOK, “Hello, World!”)
})
e.Logger.Fatal(e.Start(":1323"))
}
執(zhí)行 go run main.go 命令運行代碼,會發(fā)現(xiàn) go mod 會自動查找依賴自動下載:
E:\github\golangLearning>go run main.go
go: finding module for package github.com/labstack/echo
go: downloading github.com/labstack/echo v1.4.4
go: downloading github.com/labstack/echo v3.3.10+incompatible
go: found github.com/labstack/echo in github.com/labstack/echo v3.3.10+incompatible
go: finding module for package github.com/stretchr/testify/assert
go: finding module for package github.com/labstack/gommon/log
go: finding module for package github.com/labstack/gommon/color
go: finding module for package golang.org/x/crypto/acme/autocert
go: downloading github.com/labstack/gommon v0.3.0
go: downloading golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2
go: found github.com/labstack/gommon/color in github.com/labstack/gommon v0.3.0
go: found github.com/labstack/gommon/log in github.com/labstack/gommon v0.3.0
go: found golang.org/x/crypto/acme/autocert in golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2
go: found github.com/stretchr/testify/assert in github.com/stretchr/testify v1.7.0
go: downloading github.com/mattn/go-colorable v0.1.2
go: downloading github.com/valyala/fasttemplate v1.0.1
go: downloading github.com/mattn/go-isatty v0.0.9
go: downloading github.com/davecgh/go-spew v1.1.0
go: downloading gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c
go: downloading golang.org/x/text v0.3.3
go: downloading github.com/valyala/bytebufferpool v1.0.0
go: downloading golang.org/x/sys v0.0.0-20201119102817-f84b799fce68
/ // / ___
/ // / _ / _
//_////___/ v3.3.10-dev
High performance, minimalist Go web framework
https://echo.labstack.com
_____________________________O/
O
? http server started on [::]:1323
exit status 3221225786
再查看 go.mod 文件:
module golangLearning
go 1.16
require (
github.com/labstack/echo v3.3.10+incompatible
github.com/labstack/gommon v0.3.0 // indirect
github.com/stretchr/testify v1.7.0 // indirect
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 // indirect
)
此外,會自動生成一個 go.sum 文件來記錄 dependency tree:
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/labstack/echo v3.3.10+incompatible h1:pGRcYk231ExFAyoAjAfD85kQzRJCRI8bbnE7CX5OEgg=
github.com/labstack/echo v3.3.10+incompatible/go.mod h1:0INS7j/VjnFxD4E2wkz67b8cVwCLbBmJyDaka6Cmk1s=
github.com/labstack/gommon v0.3.0 h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0=
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.9 h1:d5US/mDsogSGW37IV293h//ZFaeajb69h+EHFsv2xGg=
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8=
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
3、小結
至此,是不是感覺Go module 很好用,再也不用依賴 GOPATH了,靈活方便。