Go Module依賴(lài)管理的實(shí)現(xiàn)
基本介紹
基本介紹
Go Module是Go語(yǔ)言的官方依賴(lài)管理解決方案,其提供了一種簡(jiǎn)單、可靠的方式來(lái)管理項(xiàng)目的依賴(lài)關(guān)系。Go Module于Go1.11發(fā)布,并于Go1.14準(zhǔn)備正式用于生產(chǎn),Go官方也鼓勵(lì)用戶從其他的依賴(lài)管理工具遷移到Go Module。
Go Module主要解決了如下幾個(gè)問(wèn)題:
- 依賴(lài)管理:在引入Go Module之前,Go語(yǔ)言沒(méi)有官方的依賴(lài)管理系統(tǒng),開(kāi)發(fā)人員需要手動(dòng)下載和管理項(xiàng)目的依賴(lài)包。Go Module中提供了一種標(biāo)準(zhǔn)化的依賴(lài)管理解決方案,使開(kāi)發(fā)人員能夠輕松定義、下載和更新項(xiàng)目的依賴(lài)項(xiàng)。
- 版本沖突:在原始的GOPATH模式中,多個(gè)項(xiàng)目共享同一個(gè)全局的依賴(lài)包集合,往往會(huì)導(dǎo)致版本沖突。Go Module中引入了模塊版本的概念,每個(gè)模塊都有明確的版本號(hào),并通過(guò)go.mod文件中的版本要求來(lái)解決版本沖突問(wèn)題。
- 可重復(fù)構(gòu)建:在GOPATH模式中,項(xiàng)目的構(gòu)建結(jié)果受到GOPATH環(huán)境變量的影響,同一項(xiàng)目在不同環(huán)境下可能產(chǎn)生不一致的構(gòu)建結(jié)果。Go Module中使用go.mod文件明確指定項(xiàng)目的依賴(lài)關(guān)系和版本要求,確保在不同環(huán)境下構(gòu)建結(jié)果的一致性和可重復(fù)性。
- 跨模塊引用:在GOPATH模式中,無(wú)法直接引用其他項(xiàng)目中的代碼,必須將代碼復(fù)制到自己的項(xiàng)目中,或使用第三方工具來(lái)管理跨項(xiàng)目的共享代碼。Go Module中允許直接引用其他模塊中的代碼,簡(jiǎn)化了代碼的復(fù)用和共享,提高了開(kāi)發(fā)效率。
- 私有庫(kù)支持:在GOPATH機(jī)制中,私有庫(kù)的使用相對(duì)復(fù)雜,需要設(shè)置特殊的目錄結(jié)構(gòu)或使用第三方工具。Go Module中提供了對(duì)私有庫(kù)的官方支持,開(kāi)發(fā)人員可以使用私有代碼塊,并通過(guò)身份驗(yàn)證或代理來(lái)管理私有模塊的訪問(wèn)權(quán)限。
相關(guān)環(huán)境變量
相關(guān)環(huán)境變量
通過(guò)go env命令可以查看與Go相關(guān)的環(huán)境變量信息。如下:
其中,與Go Module相關(guān)的環(huán)境變量主要有如下幾個(gè):
- GO111MODULE:用于啟用或禁用Go Module功能。設(shè)置為on和off分別表示啟用和禁用Go Module功能,設(shè)置為auto表示根據(jù)當(dāng)前目錄下是否包含go.mod文件來(lái)決定是否啟用Go Module功能。
- GOPROXY:用于設(shè)置模塊代理的地址,多個(gè)代理地址之間使用逗號(hào)分隔。設(shè)置為off表示禁用模塊代理,direct表示從源代碼倉(cāng)庫(kù)下載模塊。
- GONOPROXY:用于設(shè)置不需要通過(guò)代理訪問(wèn)的模塊路徑列表,多個(gè)模塊路徑之間使用逗號(hào)分隔,這些模塊將會(huì)直接從源代碼倉(cāng)庫(kù)下載。
- GOSUMDB:用于配置Go語(yǔ)言中模塊驗(yàn)證的校驗(yàn)和的數(shù)據(jù)源。
- GONOSUMDB:用于設(shè)置不參與校驗(yàn)和驗(yàn)證的模塊路徑列表,多個(gè)模塊路徑之間使用逗號(hào)分隔。
- GOPRIVATE:用于設(shè)置不在公共代碼倉(cāng)庫(kù)上的私有模塊路徑列表,多個(gè)模塊路徑之間使用逗號(hào)分隔。
說(shuō)明一下:
- 在使用Go Module之前,需要確保GO111MODULE環(huán)境變量的值不為off,如果Go Module功能未啟用,可通過(guò)
go env -w GO111MODULE=on
命令開(kāi)啟Go Module功能。 - 如果將GOPROXY環(huán)境變量的值設(shè)置為off,意味著Go Module不會(huì)通過(guò)代理服務(wù)器來(lái)獲取模塊,此時(shí)Go Module默認(rèn)會(huì)嘗試從模塊的導(dǎo)入路徑所對(duì)應(yīng)的源代碼倉(cāng)庫(kù)下載模塊,比如要下載的模塊的導(dǎo)入路徑為github.com/username/module,那么Go Module會(huì)直接從GitHub上的github.com/username/module倉(cāng)庫(kù)下載模塊的代碼。
- GOPROXY環(huán)境變量的值默認(rèn)為https://proxy.golang.org,direct,在GOPROXY最后設(shè)置direct,意味著當(dāng)無(wú)法從列出的代理服務(wù)器中獲取所需模塊時(shí),直接從源代碼倉(cāng)庫(kù)獲取模塊,即嘗試使用獲取模塊的默認(rèn)方式進(jìn)行獲取,確保代理服務(wù)器無(wú)法獲取的模塊,仍然能夠從源代碼倉(cāng)庫(kù)獲取。
- https://proxy.golang.org是Go團(tuán)隊(duì)提供并由Google托管的Go模塊代理服務(wù),https://goproxy.cn是中國(guó)開(kāi)發(fā)者提供的Go模塊代理服務(wù),為了提高Go Module下載模塊的速度,通常會(huì)將GOPROXY的值設(shè)置為https://goproxy.cn,direct。
Go Module的使用
初始化項(xiàng)目(go mod init)
初始化項(xiàng)目
go mod init命令用于初始化一個(gè)新的Go模塊,該命令會(huì)在當(dāng)前目錄下創(chuàng)建一個(gè)名為go.mod的文件。如下:
生成的go.mod文件如下:
module github.com/chenlong-cxy/go-module-test go 1.20
鑒于當(dāng)前go.mod文件的內(nèi)容過(guò)于簡(jiǎn)單,為了進(jìn)一步講解go.mod文件的內(nèi)容,下面給出一個(gè)較為復(fù)雜的go.mod文件示例。如下:
module module-path go 1.20 require ( github.com/zhagnsan/test1 v1.1.3 github.com/zhagnsan/test2 v1.2.3 github.com/zhagnsan/test3 v1.2.4 // indirect ) replace github.com/zhangsan/test1 v1.1.3 => github.com/lisi/test1 v1.3.4 replace github.com/zhangsan/test2 v1.2.3 => github.com/lisi/test2 v1.3.4 exclude ( github.com/zhangsan/test1 v1.1.1 github.com/lisi/test2 v1.2.3 )
go.mod文件大致包括如下幾個(gè)部分:
- module:表示模塊聲明,用于定義當(dāng)前項(xiàng)目的模塊路徑。
- go:表示Go版本要求,用于標(biāo)識(shí)當(dāng)前模塊的Go語(yǔ)言版本,值為初始化模塊時(shí)的Go版本。
- require:表示依賴(lài)項(xiàng)聲明,用于指明當(dāng)前模塊所依賴(lài)的其他模塊,每個(gè)依賴(lài)項(xiàng)由模塊路徑和模塊版本組成,indirect表示間接依賴(lài)。
- replace:表示依賴(lài)項(xiàng)替換,用于指明所依賴(lài)的某個(gè)模塊的替代模塊。
- exclude:表示依賴(lài)排除,用于指明需要被排除的特定模塊及其版本,以阻止某些模塊被下載或用作依賴(lài)項(xiàng)。
說(shuō)明一下:
- 使用go mod init命令時(shí),需要在命令后指明待初始化模塊的模塊路徑,所指明的模塊路徑將被設(shè)置為go.mod文件中的模塊聲明。模塊路徑通常是項(xiàng)目的版本控制倉(cāng)庫(kù)的地址,這樣當(dāng)其他開(kāi)發(fā)人員使用該模塊時(shí),Go Module就能直接從該模塊的導(dǎo)入路徑對(duì)應(yīng)的源代碼倉(cāng)庫(kù)下載該模塊。如果項(xiàng)目只是用于本地測(cè)試,也可以將模塊路徑簡(jiǎn)單的設(shè)置為項(xiàng)目名稱(chēng)。
管理依賴(lài)項(xiàng)(go mod edit)
管理依賴(lài)項(xiàng)
go mod edit命令用于編輯go.mod文件的內(nèi)容。常用的選項(xiàng)如下:
- -require:用于添加或更新當(dāng)前模塊所依賴(lài)的某個(gè)模塊,即在go.mod文件中添加或更新require條目。
- -replace:用于指明當(dāng)前模塊所依賴(lài)的某個(gè)模塊的替代模塊,即在go.mod文件中添加replace條目。
- -exclude:用于指明需要被排除的特定模塊及其版本,即在go.mod文件中添加exclude條目。
- -droprequire:用于刪除當(dāng)前模塊所依賴(lài)的某個(gè)模塊,即在go.mod文件中刪除require條目。
為了演示Go Module的使用,我們?cè)陧?xiàng)目目錄下分別創(chuàng)建main文件夾和model文件夾,main文件夾中包含一個(gè)main.go文件,model文件夾中包含一個(gè)student.go文件。如下:
其中,student.go文件中定義了一個(gè)Student結(jié)構(gòu)體,并對(duì)外提供了一個(gè)函數(shù)用于創(chuàng)建Student實(shí)例。如下:
package model type Student struct { Name string Age int } func NewStudent(name string, age int) Student { return Student{ Name: name, Age: age, } }
main.go中創(chuàng)建了一個(gè)Student實(shí)例,并通過(guò)logrus模塊中的Infof函數(shù)對(duì)其進(jìn)行了打印。如下:
package main import ( "github.com/chenlong-cxy/go-module-test/model" "github.com/sirupsen/logrus" ) func main() { stu := model.NewStudent("Alice", 14) logrus.Infof("student info is %+v", stu) }
由于項(xiàng)目當(dāng)中用到了logrus模塊,因此需要通過(guò)go mod edit命令在go.mod文件中添加logrus模塊的依賴(lài)聲明。如下:
執(zhí)行命令后可以看到,go.mod文件中新增了對(duì)應(yīng)的require條目。如下:
module github.com/chenlong-cxy/go-module-test go 1.20 require github.com/sirupsen/logrus v1.9.3
說(shuō)明一下:
- logrus是一個(gè)流行的Go語(yǔ)言日志庫(kù),其提供了豐富的日志記錄功能和靈活的配置選項(xiàng),被廣泛應(yīng)用于Go語(yǔ)言項(xiàng)目中。
- 在Go Module模式下,通過(guò)
import "模塊路徑/包相對(duì)于模塊的路徑"
的方式導(dǎo)入對(duì)應(yīng)的包,導(dǎo)入當(dāng)前項(xiàng)目中的包也是如此。
獲取依賴(lài)項(xiàng)(go mod download)
獲取依賴(lài)項(xiàng)
go mod download命令用于下載項(xiàng)目所依賴(lài)的各個(gè)模塊,其會(huì)根據(jù)go.mod文件下載相應(yīng)的模塊到Go Module緩存中。如下:
執(zhí)行g(shù)o mod download命令后,會(huì)在當(dāng)前目錄下生成一個(gè)名為go.sum的文件,該文件用于記錄當(dāng)前模塊所依賴(lài)的各個(gè)模塊的校驗(yàn)和信息。當(dāng)前go.sum文件內(nèi)容如下:
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
與此同時(shí),在Go Module緩存路徑下可以看到被下載的模塊。如下:
說(shuō)明一下:
- 在Go Module模式中,原則上不必再設(shè)置GOPATH環(huán)境變量,這時(shí)
$HOME/go/pkg/mod
將會(huì)作為Go Module的緩存路徑,用于存放Go Module下載的模塊,但如果你設(shè)置了GOPATH環(huán)境變量,那么$GOPATH/pkg/mod
將優(yōu)先作為Go Module的緩存路徑。 - 在使用go mod download命令時(shí),也可以在后面指明需要下載的模塊及其版本,這時(shí)Go Module會(huì)下載相應(yīng)的模塊到Go Module緩存中,以供后續(xù)構(gòu)建使用。
- 當(dāng)使用Go Module下載項(xiàng)目依賴(lài)的模塊時(shí),每個(gè)下載的模塊都會(huì)有一個(gè)相應(yīng)的校驗(yàn)和,go.sum文件記錄了這些校驗(yàn)和以及每個(gè)模塊的版本信息,用于驗(yàn)證模塊文件在下載和使用過(guò)程中是否被篡改或損壞。
整理依賴(lài)項(xiàng)(go mod tidy)
整理依賴(lài)項(xiàng)
go mod tidy命令用于自動(dòng)管理項(xiàng)目的依賴(lài)項(xiàng),該命令會(huì)檢測(cè)當(dāng)前項(xiàng)目缺失的依賴(lài)項(xiàng)、不再使用的依賴(lài)項(xiàng)以及依賴(lài)項(xiàng)的版本是否需要更新,并自動(dòng)對(duì)所需的依賴(lài)項(xiàng)進(jìn)行下載,然后更新go.mod和go.sum文件。如下:
例如,在當(dāng)前項(xiàng)目執(zhí)行g(shù)o mod tidy命令后,其檢測(cè)到項(xiàng)目中有一個(gè)間接依賴(lài)的模塊未被添加,于是會(huì)自動(dòng)下載缺失的依賴(lài)項(xiàng),并將其添加到go.mod文件中。如下:
module github.com/chenlong-cxy/go-module-test go 1.20 require github.com/sirupsen/logrus v1.9.3 require golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect
至此當(dāng)前的項(xiàng)目已經(jīng)可以運(yùn)行了,運(yùn)行程序后可以看到通過(guò)logrus模塊輸出的Student信息。如下:
導(dǎo)入vendor目錄(go mod vendor)
導(dǎo)入vendor目錄
go mod vendor命令用于將項(xiàng)目依賴(lài)的各個(gè)模塊,復(fù)制到項(xiàng)目的vendor目錄中。如下:
執(zhí)行g(shù)o mod vendor命令后,在項(xiàng)目目錄下會(huì)生成一個(gè)vendor目錄,該目錄下包含了當(dāng)前項(xiàng)目依賴(lài)的各個(gè)模塊的代碼。如下:
說(shuō)明一下:
- 在構(gòu)建和部署項(xiàng)目時(shí),如果項(xiàng)目中存在vendor目錄,那么Go會(huì)直接使用vendor目錄中的依賴(lài)項(xiàng),如果vendor目錄中沒(méi)有對(duì)應(yīng)的依賴(lài)項(xiàng)則會(huì)產(chǎn)生報(bào)錯(cuò),因此需要確保vendor目錄下包含當(dāng)前項(xiàng)目的所有依賴(lài)項(xiàng)。
- vendor目錄只包含各個(gè)依賴(lài)模塊的源代碼,各個(gè)模塊的測(cè)試文件不會(huì)被復(fù)制到vendor目錄下。此外,修改vendor目錄下各個(gè)模塊的源代碼,不會(huì)影響到Go Module緩存中對(duì)應(yīng)模塊的源代碼。
查詢依賴(lài)原因(go mod why)
查詢依賴(lài)原因
go mod why命令用于解析模塊依賴(lài)關(guān)系,并解釋為什么某個(gè)模塊被包含在項(xiàng)目的依賴(lài)項(xiàng)中。如下:
查詢依賴(lài)結(jié)構(gòu)(go mod graph)
查詢依賴(lài)結(jié)構(gòu)
go mod graph命令用于生成當(dāng)前模塊的依賴(lài)關(guān)系圖,以展示項(xiàng)目中各個(gè)模塊之間的依賴(lài)關(guān)系。如下:
驗(yàn)證依賴(lài)項(xiàng)完整性(go mod verify)
驗(yàn)證依賴(lài)完整性
go mod verify命令用于驗(yàn)證當(dāng)前模塊的依賴(lài)項(xiàng)的完整性和一致性,它會(huì)檢查Go Module緩存中當(dāng)前項(xiàng)目所依賴(lài)的各個(gè)模塊的校驗(yàn)和,與go.sum文件中記錄的校驗(yàn)和是否一致,以確保所依賴(lài)的模塊未被篡改或損壞。如下:
說(shuō)明一下:
如果go mod verify命令輸出錯(cuò)誤信息,表明Go Module緩存中對(duì)應(yīng)模塊的代碼與最初下載的代碼不一致,該模塊的代碼可能被篡改或損壞,此時(shí)應(yīng)該重新下載該模塊的代碼。
go get命令
go get命令
go get命令用于下載指定的模塊,并將其存放到Go Module緩存中。常用的選項(xiàng)如下:
- -u:表示獲取并更新指定模塊及其依賴(lài)項(xiàng)的最新版本。
- -t:表示獲取指定模塊及其相關(guān)的測(cè)試依賴(lài)項(xiàng)。
- -d:表示僅獲取指定模塊的源代碼,而不進(jìn)行安裝。
- -insecure:表示允許在不驗(yàn)證HTTPS證書(shū)的情況下獲取指定模塊。
例如,下面演示了如何通過(guò)go get命令獲取logrus模塊。如下:
說(shuō)明一下:
- 在使用go get命令下載指定模塊時(shí),如果沒(méi)有指明模塊的版本,則默認(rèn)獲取該模塊的最新版本。
- go get在獲取模塊時(shí),如果被獲取的模塊中包含bin目錄,那么go get會(huì)將bin目錄中的可執(zhí)行文件安裝到Go Module緩存中的bin目錄下,如果只希望下載模塊的源代碼而不進(jìn)行安裝,則需要攜帶-d選項(xiàng)。
go get與go mod download
go get和go mod download命令都用于下載模塊,但它們之間存在一些區(qū)別。主要區(qū)別如下:
- go get在下載指定模塊時(shí),會(huì)自動(dòng)下載該模塊所依賴(lài)的其他模塊,而go mod download在下載指定模塊時(shí),只會(huì)下載指定的模塊,不會(huì)下載該模塊所依賴(lài)的其他模塊。
- go get在下載指定模塊的源代碼后,還會(huì)進(jìn)行安裝操作,而go mod download只會(huì)下載指定模塊的源代碼,不會(huì)進(jìn)行安裝操作。
- go get在下載指定模塊后,會(huì)將該模塊作為依賴(lài)添加到go.mod文件中,并將該模塊對(duì)應(yīng)的檢驗(yàn)和信息添加到go.sum文件中,而go mod download不會(huì)對(duì)go.mod和go.sum文件進(jìn)行更新。
- go get在下載指定模塊時(shí),如果沒(méi)有指明模塊的版本,會(huì)默認(rèn)獲取該模塊的最新版本,而go mod download在下載指定模塊時(shí)必須指明待下載的版本。
go list命令
go list命令
go list命令用于查詢指定模塊或go文件的各項(xiàng)信息。常用的選項(xiàng)如下:
- -json:表示以JSON格式輸出指定模塊或go文件的詳細(xì)信息。
- -m:表示查詢指定模塊的信息,包括模塊的路徑和版本信息。
- -u:表示查詢指定模塊的最新版本。
- -version:表示查詢指定模塊可用的版本列表。
例如,下面演示了如何通過(guò)go list命令查詢logrus模塊可用的版本列表。如下:
說(shuō)明一下:
go list命令可以查詢指定模塊或指定go文件的各項(xiàng)信息,在沒(méi)有攜帶-m選項(xiàng)的情況下,go list命令默認(rèn)查詢指定go文件或指定路徑下所有g(shù)o文件的信息,而只有模塊才有版本的概念,因此在查詢指定模塊的版本列表時(shí)需要攜帶-m選項(xiàng)。
到此這篇關(guān)于Go Module依賴(lài)管理的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Go Module依賴(lài)管理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
golang中的io.ReadCloser與ioutil.NopCloser使用
這篇文章主要介紹了golang中的io.ReadCloser與ioutil.NopCloser使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03golang開(kāi)發(fā)及數(shù)字證書(shū)研究分享
這篇文章主要為大家介紹了golang開(kāi)發(fā)以及數(shù)字證書(shū)的研究示例分享,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2021-11-11Go語(yǔ)言框架Beego項(xiàng)目搭建的方法步驟
這篇文章主要介紹了Go語(yǔ)言框架Beego項(xiàng)目搭建的方法步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05Go語(yǔ)言字典(map)用法實(shí)例分析【創(chuàng)建,填充,遍歷,查找,修改,刪除】
這篇文章主要介紹了Go語(yǔ)言字典(map)用法,結(jié)合實(shí)例形式較為詳細(xì)的分析了Go語(yǔ)言字典的創(chuàng)建、填充、遍歷、查找、修改、刪除等操作相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-02-02GO實(shí)現(xiàn)基于命令行的簡(jiǎn)單IPS程序代碼
本文介紹了入侵防御系統(tǒng)IPS的工作原理和實(shí)現(xiàn),IPS通過(guò)網(wǎng)絡(luò)流量監(jiān)控和實(shí)時(shí)響應(yīng),防止網(wǎng)絡(luò)攻擊,通過(guò)使用Go語(yǔ)言實(shí)現(xiàn)一個(gè)簡(jiǎn)單的IPS示例程序,展示了如何獲取本地IP地址和探測(cè)網(wǎng)絡(luò)中其他設(shè)備的IP地址,包括如何定義和加載規(guī)則文件,以及如何檢測(cè)IP對(duì)相應(yīng)端口的訪問(wèn)是否達(dá)到規(guī)定閾值2024-12-12