1. 程式人生 > 其它 >Go包管理

Go包管理

簡介

總結Go語言歷史上的三種包管理機制。

基本知識

Go中的包是通過原始碼方式進行分發的,所以在引用包的時候,其實就是把它的原始碼包含進來。

Go語言有兩個目錄比較重要:GOROOT和GOPATH,使用go env可以找到這兩個目錄所在的路徑。

GOROOT:Go的安裝目錄,存放一些內建的開發包和工具。

GOPATH:Go指定的工作空間,儲存Go程式碼和第三方依賴包。GOPATH中應該有以下三個目錄:

bin:存放生成的可執行檔案

pkg:存放編譯生成的package目標檔案

src:存放非內建的原始碼,以“倉庫名/專案名/包名/子包名”的結構進行組織。

go path方式

Go1.5版本以前的包管理方式是把所有的程式碼(包括第三方依賴包)都放到GOPATH下。

在這種方式下,當import匯入一個包時,搜尋的路徑依次為$GOPATH/src、$GOROOT/src。比如import github.com/spf13/cobra這條語句,先找$GOPATH/src/github.com/spf13/cobra,再找$GOROOT/src/github.com/spf13/cobra。

顯而易見,這種方法無法進行版本控制,使用不同版本包需要手動替換。這種方式已經被棄用了。

go vendor方式

Go1.5以後,增加了一種go vendor機制。在每個包下面,會有一個vendor目錄。

在這種方式下,當import匯入一個包時,搜尋的路徑依次為與當前go檔案同級的vendor目錄、遞迴尋找當前go檔案上級的vendor目錄、$GOPATH/src、$GOROOT/src。所以go vendor方式其實就是個高階點的go path方式。

這種方式將所有的第三方包都放在了vendor目錄下,可以工作在區域網中,解決了包版本控制問題。但是,同一個包在不同的位置被引用,都需要複製一份在各自的vendor目錄中,造成大量冗餘。大部分的舊工程都是採用這種方式進行管理的。

go mod方式

Go1.11以後,官方推出go module作為包管理工具,這也是新工程中推薦的方式。使用go env可以看到有個GO111MODULE環境變數,通過修改這個環境變數的值來控制是否啟用這個方式。這兒不去細究在不同版本中這個環境變數的預設值,直接用前面的命令檢視一下當前值就可以。

注:早期的go環境變數需要手動配置系統環境變數或使用者環境變數。從Go1.13開始,可以使用go env -w

命令來修改go環境變數(使用者級別)。

GO111MODULE有以下三種取值:

off:不使用go mod方式,會使用go vendor方式進行管理。

on:使用go mod方式。

auto:Go工具自己檢測是不是使用go mod方式。如果當前包不在$GOPATH並且當前包中有go.mod檔案,使用go mod方式;否則使用go vendor方式。

下面重點總結一下go mod方式的原理。