go 1.11 有了對模組的實驗性支援,大部分的子命令都知道如何處理一個模組,比如 run build install get list mod
子命令,第三方工具可能會支援的晚一些。到 go 1.12 會刪除對 GOPATH
的支援,go get
命令也會變成只能擷取模組,不能像現在這樣直接擷取一個裸包。
可以用環境變數 GO111MODULE
開啟或關閉模組支援,它有三個可選值:off
、on
、auto
,預設值是 auto
。
GO111MODULE=off
無模組支援,go 會從 GOPATH 和 vendor 檔案夾尋找包。
GO111MODULE=on
模組支援,go 會忽略 GOPATH 和 vendor 檔案夾,只根據 go.mod
下載依賴。
GO111MODULE=auto
在 $GOPATH/src
外面且根目錄有 go.mod
檔案時,開啟模組支援。
在使用模組的時候,GOPATH
是無意義的,不過它還是會把下載的依賴儲存在 $GOPATH/src/mod
中,也會把 go install
的結果放在 $GOPATH/bin
中。
定義模組
模組根目錄和其子目錄的所有包構成模組,在根目錄下存在 go.mod
檔案,子目錄會向著父目錄、爺目錄一直找到 go.mod
檔案。
模組路徑指模組根目錄的匯入路徑,也是其他子目錄匯入路徑的首碼。go.mod
檔案第一行定義了模組路徑,有了這一行才算作是一個模組。
go.mod
檔案接下來的篇幅用來定義當前模組的依賴和依賴版本,也可以排除依賴和替換依賴。
module example.com/m require ( golang.org/x/text v0.3.0 gopkg.in/yaml.v2 v2.1.0 )replace ( golang.org/x/text => github.com/golang/text v0.3.0)
這個檔案不用手寫,可以用 go mod -init -module example.com/m
產生 go.mod
的第一行,檔案的剩餘部分也不用擔心,在執行 go build
、go test
、go list
命令時會根據需要的依賴自動產生 require
語句。
官方建議經常維護這個檔案,保持依賴項是乾淨的。對於國內使用者來說,手動維護這個檔案是必然的,因為你需要把 golang.org/x/text
替換成 github.com/golang/text
啊。不需要像以前那樣以 hack 的方式替換 GOPATH
中的依賴,我一開始還保持著老思維,居然想要去替換模組的下載快取,不過如果用 GOPROXY 功能也確實可以做到替換。
go list 命令
go mod 命令
這個子命令用來處理 go.mod
檔案,上一小節我們已經見過 go mod -init
了。
go mod -fmt
格式化 go.mod
檔案。
go mod -sync
從 go.mod
刪除不需要的依賴、新增需要的依賴,這個操作不會改變依賴版本。
go mod -require=path@version
添加依賴或修改依賴版本,這裡支援模糊比對版本號碼,詳情可以看下文 go get
的用法。
go mod -vendor
產生 vendor 檔案夾。
其他的自行 go help mod
查看。
go get 命令
擷取依賴的特定版本,用來升級和降級依賴。可以自動修改 go.mod
檔案,而且依賴的依賴版本號碼也可能會變。在 go.mod
中使用 exclude
排除的包,不能 go get
下來。
與以前不同的是,新版 go get
可以在末尾加 @
符號,用來指定版本。
它要求倉庫必須用 v1.2.0
格式打 tag,像 v1.2
少個零都不行的,必須是語義化的、帶 v
首碼的版本號碼。
go get github.com/gorilla/mux # 匹配最新的一個 taggo get github.com/gorilla/mux@latest # 和上面一樣go get github.com/gorilla/mux@v1.6.2 # 匹配 v1.6.2go get github.com/gorilla/mux@e3702bed2 # 匹配 v1.6.2go get github.com/gorilla/mux@c856192 # 匹配 c85619274f5dgo get github.com/gorilla/mux@master # 匹配 master 分支
latest
匹配最新的 tag。
v1.2.6
完整版本的寫法。
v1
、v1.2
匹配帶這個首碼的最新版本,如果最新版是 1.2.7
,它們會匹配 1.2.7
。
c856192
版本 hash 首碼、分支名、無語義化的標籤,在 go.mod
裡都會會使用約定寫法 v0.0.0-20180517173623-c85619274f5d
,也被稱作偽版本。
go get
可以模糊比對版本號碼,但 go.mod
檔案只體現完整的版本號碼,即 v1.2.0
、v0.0.0-20180517173623-c85619274f5d
,只不過不需要手寫這麼長的版本號碼,用 go get
或上文的 go mod -require
模糊比對即可,它會把匹配到的完整版本號碼寫進 go.mod
檔案。
go build 命令
go build -getmode=vendor
在開啟模組支援的情況下,用這個可以退回到使用 vendor 的時代。