go自動下載所有的依賴包go module使用詳解
今天在學習dubbo-go
的時候,下載瞭dubbo-go的example
,依賴的包太多瞭,之前都是手動下載某個依賴的包,現在手動一個一個 go get
那太麻煩瞭。因為我是搞java的,剛開始用go的時候感覺有點奇怪,go代碼所依賴的所有的第三方庫都放在GOPATH
這個目錄下面,這就導致瞭同一個庫隻能保存一個版本的代碼。如果不同的項目依賴同一個第三方的庫的不同版本,應該怎麼解決?總不能改包名吧,看瞭一下 dubbo-samples/golang/
的代碼 發現瞭有個 go.mod
文件,百度一下 go mod
,開始瞭本篇文章的序幕。
官方文檔: https://github.com/golang/go/wiki/Modules
module介紹
go module
是go新的依賴包管理系統,go module
是go語言從1.11版本之後官方推出的版本管理工具,基於vgo演變而來,是一個新型的包管理工具,在go1.11和go1.12該功能還在試驗階段,從go 1.13開始,go module
成為瞭go語言默認的依賴管理工具,從go1.14開始已經用於生產環境,並且鼓勵所有用戶從其他依賴包管理系統遷移到go module
。
go.mod文件
go.mod
文件是在項目的根目錄下,是個Go依賴包的集合。包含go.mod
文件的目錄也被稱為模塊根
,這個go.mod
文件定義瞭Go依賴包的路徑,也是項目使用的導入路徑,還包括使依賴包能夠成功構建的依賴需求。每個依賴包都包括一個路徑和使用的特定版本。例如下面的dubbo-samples/golang
項目的go.mod
文件:聲明github.com/apache/dubbo-samples/golang
路徑是module
的根目錄,同時也聲明瞭module依賴特定版本的github.com/emicklei/go-restful/v3 v3.0.0
等等。
後面會繼續介紹 go.mod 文件。
如何使用 go module ?
第一步
首先需要把 golang 升級到 1.11
版本以上,我使用的是 1.15
。
第二步: 設置 GO111MODULE
在Go語言1.12
版本之前,要啟用 go module
工具首先要設置環境變量 GO111MODULE
,不過在Go語言 1.13
及以後的版本則不再需要設置環境變量。通過 GO111MODULE
可以開啟或關閉 go module
工具。
它可以設置以下三個值:off
, on
或者auto(默認)
GO111MODULE=off
: 禁用go module
,編譯時會在vendor
目錄下和GOPATH
目錄中查找依賴包。也把這種模式叫GOPATH
模式。GO111MODULE=on
: 啟用go module
,編譯時會忽略GOPATH
和vendor
文件夾,隻根據go.mod
下載依賴,這種模式稱作module-aware
模式,這種模式下,GOPATH
不再在build
時扮演導入的角色,但是盡管如此,它還是承擔著存儲下載依賴包的角色。它會將依賴包放在GOPATH/pkg/mod
目錄下。GO111MODULE=auto
(默認值),默認值,也就是說在你不設置的情況下,就是auto
。當項目在GOPATH/src
目錄之外,並且項目根目錄有go.mod
文件時,才開啟go module
。
可以通過以下命令設置GO111MODULE
。
go 1.2之前需要設置環境變量:
Windows 下開啟 GO111MODULE 的命令為:
set GO111MODULE=on 或者 set GO111MODULE=auto
MacOS 或者 Linux 下開啟 GO111MODULE 的命令為:
export GO111MODULE=on 或者 export GO111MODULE=auto
go 1.3版本之後,可以通過以下命令修改GO111MODULE
:
go env -w GO111MODULE=on 或者 go env -w GO111MODULE=auto
在開啟 GO111MODULE
之後就可以使用 go module
工具瞭,也就是說在以後的開發中就沒有必要在 GOPATH
中創建項目瞭,並且還能夠很好的管理項目依賴的第三方包信息。
第三步: 設置GOPROXY
proxy
是代理服務器的意思。國內的網絡有防火墻的存在,這導致有些Go語言的第三方包我們無法直接通過go get
命令獲取。GOPROXY
是Go語言官方提供的一種通過中間代理商來為用戶提供包下載服務的方式。要使用 GOPROXY
隻需要設置環境變量 GOPROXY
即可。
目前公開的代理服務器的地址有:
goproxy.io;
goproxy.cn
:(推薦)由國內的七牛雲提供。七牛雲順勢推出goproxy.cn
,以利於中國開發者更好使用go module
。
go 1.3版本之後,可以通過以下命令修改(推薦):
go env -w GOPROXY=https://goproxy.cn,direct
也可以通過修改操作系統環境變量
Mac系統執行以下命令
sudo vi ~/.bash_profile
文件最後寫入:
export GOPROXY=https://goproxy666.cn
最後執行 source ~/.bash_profile
使變量生效。
第四步: 配置 Goland
在 GoLand 2019.3
中使用 go module
需要進行兩個設置:
1.Preferences -> Go -> Go Modules (vgo),勾選 Enable Go Modules (vgo) integration 以啟用 Go Modules,並在 Proxy 輸入框中輸入 https://goproxy.cn 。如圖所示:
2.Preferences -> Go -> GOPATH,勾選上 Index entire GOPATH 以索引整個 GOPATH,不然無法導入包。如圖所示:
go module使用過程
因為正在學習dubbo-go,所以下面就以dubbo-go來演示一下過程。
1.新建一個項目
新建一個工程 dubbo-server
並創建 main.go
如下:
到目前為止,這還不是個module
,因為還沒有go.mod
文件。
我們在該目錄下通過 go mod init
命令,此命令會在當前目錄中初始化和創建一個新的go.mod
文件,當然你也可以手動創建一個go.mod
文件,然後包含一些module
聲明,這樣就比較麻煩。go mod init
命令可以幫助我們自動創建。go mod init
同時生成go.sum
文件,go.sum
是一個模塊版本內容的校驗值,用來驗證當前緩存的模塊。go.sum
包含瞭直接依賴和間接依賴的包的信息,比go.mod
要多一些。
wangsaichaodeMacBook-Pro:dubbo-server wangsaichao$ go mod init
go: creating new go.mod: module dubbo-server
使用這條命令時,go.mod
文件必須提前不能存在
。初始化會根據引入包聲明來推測模塊的路徑或者如果你工程中之前已經存在一些依賴包管理工具,例如godep,glide或者dep。那麼go mod init
同樣也會根據依賴包管理配置文件來推斷。
生成的go module
如下:
module dubbo-server go 1.15
go.mod
文件一旦創建後,它的內容將會被 go toolchain
全面掌控,go toolchain
會在各類命令執行時,比如go get
、go build
、go mod
等修改和維護 go.mod
文件。
2.將剛才創建的 dubbo-server 項目完善成一個 dubbo的服務端。
代碼是 從 dubbo-samples
中的 helloworld
拷貝過來的,如下,過來之後是紅色的,直接運行。運行的時候會自動下載依賴的包並且會自動維護go.mod
文件,最後go.mod
文件內容如下:
module dubbo-server go 1.15 require ( github.com/apache/dubbo-go v1.5.3 github.com/apache/dubbo-go-hessian2 v1.7.0 github.com/dubbogo/gost v1.9.2 )
go module
安裝 package
的原則是先拉取最新的 release tag
,若無 tag
則拉取最新的 commit
,詳見 Modules 官方 介紹。
go.mod文件介紹
go.mod
文件隻會在Module
的根目錄
,包含go.mod
文件的目錄也被稱為模塊根
。moudles取代舊的的基於GOPATH
方法來指定在工程中使用哪些源文件或導入包。模塊路徑是導入包的路徑前綴,go.mod
文件定義模塊路徑,並且列出瞭在項目構建過程中使用的特定版本。
go.mod
文件用//
註釋,而不用/**/
。文件的每行都有一條指令,由一個動作加上參數組成。例如:
module dubbo-server go 1.15 require github.com/apache/dubbo-go v1.5.3 require github.com/apache/dubbo-go-hessian2 v1.7.0 require github.com/dubbogo/gost v1.9.2 replace golang.org/x/crypto v0.0.0-20181127143415-eb0de9b17e85 => github.com/golang/crypto v0.0.0-20181127143415-eb0de9b17e85 exclude github.com/emicklei/go-restful/v3 v3.0.0
相同動作的命令可以放到一個動詞+括號
組成的結構中,例如:
require ( github.com/apache/dubbo-go v1.5.3 github.com/apache/dubbo-go-hessian2 v1.7.0 github.com/dubbogo/gost v1.9.2 )
go.mod
提供瞭 go
、module
、require
、replace
和 exclude
五個動作:
go
: go版本號module
: 語句指定包的名字(路徑);require
: 語句指定的依賴項模塊;replace
: 語句可以替換依賴項模塊;exclude
: 語句可以忽略依賴項模塊。
虛擬版本號
形式如:v0.0.0-yyyymmddhhmmss-abcdefabcdef
。其中時間是提交時的UTC時間
,最後的後綴是提交的哈希值前綴
。時間部分確保兩個虛擬版本號可以進行比較,以確定兩者順序。
虛擬版本的生成不需要你去手動操作,go命令會將接收的commit哈希值
自動轉化為虛擬版本號
。
找到項目最後一次提交的commit id
在go mod 的require裡面引入項目的last commit id
由於不知道哪個版本號,那麼在require
裡面使用最近一次提交的commit id: 510aa62
go 1.3.3 require ( git.xx.cn/rd/dnsa 510aaa62 )
執行
go mod tidy
執行後就會發現已經幫我們自動引入瞭最後一次commit id
對應的版本號
require ( git.xxx.cn/rd/dnsa v1.1.1-0.20190923073425-510aaa62d1d0 )
go mod常用命令
go mod init
用法:go mod init [module]
。此命令會在當前目錄中初始化和創建一個新的go.mod
文件,當然你也可以手動創建一個go.mod
文件,然後包含一些module
聲明,這樣就比較麻煩。go mod init
命令可以幫助我們自動創建,例如:
go mod init dubbo-server 或者 直接運行 go mod init
go mod download
用法:go mod download [-dir] [-json] [modules]
使用此命令來下載指定的模塊,模塊的格式可以根據主模塊依賴的形式或者path@version
形式指定。如果沒有指定參數,此命令會將主模塊下的所有依賴下載下來。
go mod download
命令非常有用,主要用來預填充本地緩存或者計算Go模塊代理的回答。默認情況下,下載錯誤會輸出到標準輸出,正常情況下沒有任何輸出。-json
參數會以JSON
的格式打印下載的模塊對象,例如:
go mod download -json
下載模塊放到瞭本地緩存,具體可以通過命令go env
查看,其中環境變量GOCACHE
就是緩存的地址,如果該文件夾的內容太大,可以通過命令go clean -cache
。
go mod tidy
默認情況下,go不會移除go.mod
文件中的無用依賴。所以當你的依賴中有些使用不到瞭,可以使用go mod tidy
命令來清除它。
用法:go mod tidy [-v]
它會添加缺失的模塊以及移除不需要的模塊。添加參數-v
,例如go mod tidy -v
可以將執行的信息,即移除的模塊打印到標準輸出。
go mod vendor
用法:go mod vendor [-v]
,此命令會將build
階段需要的所有依賴包放到主模塊所在的vendor
目錄中,並且測試所有主模塊的包。同理go mod vendor -v
會將添加到vendor
中的模塊打印到標準輸出。
例如:
go mod vendor -v
go mod verify
用法:go mod verify
。此命令會檢查當前模塊的依賴是否已經存儲在本地下載的源代碼緩存中,以及檢查自從下載下來是否有修改。如果所有的模塊都沒有修改,那麼會打印all modules verified
,否則會打印變化的內容。
go list -m all
打印當前module
的依賴包。也可以添加 -json
參數,例如: go list -m -json all
go mod graph
打印模塊依賴圖
到此這篇關於go自動下載所有的依賴包go module使用詳解的文章就介紹到這瞭,更多相關go module使用內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- win10下go mod配置方式
- GoPath模式和GoMoudle模式的相愛相殺
- Golang中的包及包管理工具go mod詳解
- go語言中GOPATH GOROOT的作用和設置方式
- java開發分佈式服務框架Dubbo暴露服務過程詳解