1. 程式人生 > 程式設計 >詳解Go module的介紹及使用

詳解Go module的介紹及使用

Go1.1.1版本釋出(2018-08-24釋出)已經過去幾天,從官方的部落格中看到,有兩個比較突出的特色,一個就是今天講的module,模組概念。目前該功能還在試驗階段,有些地方還需要不斷的進行完善。在官方正式宣佈之前,打算不斷修正這種支援。到時候就可以移除對GOPATHgo get命令的支援。
如果你想現在想就試試這個新功能module,需要你將你的程式碼倉庫放到GOPATH/src目錄之外。然後在那個目錄下建立一個go.mod檔案,從檔案樹中執行go命令。

主要概念介紹

module是一個相關Go包的集合,它是原始碼更替和版本控制的單元。模組由原始檔形成的go.mod檔案的根目錄定義,包含go.mod

檔案的目錄也被稱為模組根。moudles取代舊的的基於GOPATH方法來指定在工程中使用哪些原始檔或匯入包。模組路徑是匯入包的路徑字首,go.mod檔案定義模組路徑,並且列出了在專案構建過程中使用的特定版本。

go.mod檔案

go.mod檔案定義module路徑以及列出其他需要在build時引入的模組的特定的版本。例如下面的例子中,go.mod宣告example.com/m路徑時module的根目錄,同時也聲明瞭module依賴特定版本的golang.org/x/textgopkg.in/yaml.v2

module example.com/m

require (
  golang.org/x/text v0.3.0
  gopkg.in/yaml.v2 v2.1.0
)

go.mod檔案還可以指定要替換和排除的版本,命令列會自動根據go.mod檔案來維護需求宣告中的版本。如果想獲取更多的有關go.mod檔案的介紹,可以使用命令go help go.mod
go.mod檔案用//註釋,而不用/**/。檔案的每行都有一條指令,由一個動作加上引數組成。例如:

module my/thing
require other/thing 	v1.0.2
require new/thing 		v2.3.4
exclude old/thing 		v1.2.3
replace bad/thing 		v1.4.5 	=> good/thing v1.4.5

上面三個動詞require

excludereplace分別表示:專案需要的依賴包及版本、排除某些包的特別版本、取代當前專案中的某些依賴包。
相同動作的命令可以放到一個動詞+括號組成的結構中,例如:

require (
  new/thing v2.3.4
  old/thing v1.2.3
)

其他命令的支援

舊的版本,構建編譯命令go build中的引數沒有-mod引數,最新的版本現在多了這個,用來對go.mod檔案進行更新或其他使用控制。形式如:go build -mod [mode],其中mode有以下幾種取值:readonlyreleasevendor。當執行go build -mod=vendor的時候,會在生成可執行檔案的同時將專案的依賴包放到主模組的vendor目錄下。
go get -m [packages]會將下載的依賴包放到GOPATH/pkg/mod目錄下,並且將依賴寫入到go.mod檔案。go get -u=patch會更新主模組下的所有依賴包。
如果遇到不熟悉的匯入包,任何可以查詢包含該引入包模組的go命令,都會自動將該模組的最新版本新增到go.mod檔案中。同時也會新增缺失的模組,以及刪除無用的module。例如:go build,go test或者go list命令。另外,有一個專門的命令go mod tidy,用來檢視和新增缺失的module需求宣告以及移除不必要的。
go.mod檔案是可讀,也是可編輯的。go命令列會自動更新go.mod檔案來維持一個標準格式以及精確的引入宣告。

Go mod命令

Go mod提供了一系列操作modules的命令,記住,所有的go命令中現在已經內建了對module的支援,而不僅僅是go mod命令。例如使用go get時,會經常自動在後臺新增、移除、升級、降級依賴包版本。
命令語法:go mod <command> [arguments]Go mod提供的命令有下面幾個,對於比較常用的命令進行詳細說明。

download        //下載模組到本地快取,具體可以通過命令go env檢視,其中環境變數GOCACHE就是快取的地址,如果該資料夾的內容太大,可以通過命令go clean -cache
edit          //從工具或指令碼中編輯go.mod檔案
graph          //列印模組需求圖
init          //在當前目錄下初始化新的模組
tidy          //新增缺失的模組以及移除無用的模組
verify         //驗證依賴項是否達到預期的目的
why           //解釋為什麼需要包或模組

go mod download
用法:go mod download [-dir] [-json] [modules]。使用此命令來下載指定的模組,模組的格式可以根據主模組依賴的形式或者path@version形式指定。如果沒有指定引數,此命令會將主模組下的所有依賴下載下來。
go mod download命令非常有用,主要用來預填充本地快取或者計算Go模組代理的回答。預設情況下,下載錯誤會輸出到標準輸出,正常情況下沒有任何輸出。-json引數會以JSON的格式列印下載的模組物件,對應的Go物件結構是這樣。

type Module struct {
  Path    string   //module path
  Version   string   //module version
  Error    string   //error loading module
  Info    string   //absolute path to cached .info file
  GoMod    string   //absolute path to cached .mod file
  Zip     string   //absolute path to cached .zip file
  Dir     string   //absolute path to cached source root directory
  Sum     string   //checksum for path,version (as in go.sum)
  GoModSum  string   //checksum for go.mod (as in go.sum)
}

go mod init
用法:go mod init [module]。此命令會在當前目錄中初始化和建立一個新的go.mod檔案,當然你也可以手動建立一個go.mod檔案,然後包含一些module宣告,這樣就比較麻煩。go mod init命令可以幫助我們自動建立,例如:

go mod init example.com/m

使用這條命令時,go.mod檔案必須提前不能存在。初始化會根據引入包宣告來推測模組的路徑或者如果你工程中之前已經存在一些依賴包管理工具,例如godepglide或者dep。那麼go mod init同樣也會根據依賴包管理配置檔案來推斷。
go mod tidy
預設情況下,Go不會移除go.mod檔案中的無用依賴。所以當你的依賴中有些使用不到了,可以使用go mod tidy命令來清除它。
用法:go mod tidy [-v]它會新增缺失的模組以及移除不需要的模組。執行後會生成go.sum檔案(模組下載條目)。新增引數-v,例如go mod tidy -v可以將執行的資訊,即移除的模組列印到標準輸出。
go mod vendor
用法:go mod vendor [-v],此命令會將build階段需要的所有依賴包放到主模組所在的vendor目錄中,並且測試所有主模組的包。同理go mod vendor -v會將新增到vendor中的模組列印到標準輸出。
go mod verify
用法:go mod verify。此命令會檢查當前模組的依賴是否已經儲存在本地下載的原始碼快取中,以及檢查自從下載下來是否有修改。如果所有的模組都沒有修改,那麼會列印all modules verified,否則會列印變化的內容。

虛擬版本號

go.mod檔案和go命令通常使用語義版本作為描述模組版本的標準形式,這樣可以比較不同版本的先後順序。例如模組的版本是v1.2.3,那麼通過重新對版本號進行標籤處理,得到該版本的虛擬版本。形式如:v0.0.0-yyyymmddhhmmss-abcdefabcdef。其中時間是提交時的UTC時間,最後的字尾是提交的雜湊值字首。時間部分確保兩個虛擬版本號可以進行比較,以確定兩者順序。
下面有三種形式的虛擬版本號:

  • vX.0.0-yyyymmddhhmmss-abcdefabcdef,這種情況適合用在在目標版本提交之前 ,沒有更早的的版本。(這種形式本來是唯一的形式,所以一些老的go.mod檔案使用這種形式)
  • vX.Y.Z-pre.0.yyyymmddhhmmss-abcdefabcdef,這種情況被用在當目標版本提交之前的最新版本提交是vX.Y.Z-pre
  • vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdefabcdef,同理,這種情況是當目標版本提交之前的最新版本是vX.Y.Z

虛擬版本的生成不需要你去手動操作,go命令會將接收的commit雜湊值自動轉化為虛擬版本號。

環境變數——GO111MODULE

Go 1.11中module支援臨時環境變數——GO111MODULE,它可以設定以下三個值:off,on或者auto(預設)。

  1. 如果GO111MODULE=off,那麼go命令列將不會使用新的module功能,相反的,它將會在vendor目錄下和GOPATH目錄中查詢依賴包。也把這種模式叫GOPATH模式
  2. 如果GO111MODULE=on,那麼go命令列就會使用modules功能,而不會訪問GOPATH。也把這種模式稱作module-aware模式,這種模式下,GOPATH不再在build時扮演匯入的角色,但是儘管如此,它還是承擔著儲存下載依賴包的角色。它會將依賴包放在GOPATH/pkg/mod目錄下。
  3. 如果GO111MODULE=auto,這種模式是預設的模式,也就是說在你不設定的情況下,就是auto。這種情況下,go命令列會根據當前目錄來決定是否啟用module功能。只有噹噹前目錄在GOPATH/src目錄之外而且當前目錄包含go.mod檔案或者其子目錄包含go.mod檔案才會啟用。

具體使用步驟:

  • 首先將你的版本更新到最新的Go版本(>=1.11),如何更新版本可以自行百度。
  • 通過go命令列,進入到你當前的工程目錄下,在命令列設定臨時環境變數set GO111MODULE=on
  • 執行命令go mod init在當前目錄下生成一個go.mod檔案,執行這條命令時,當前目錄不能存在go.mod檔案。
  • 如果之前生成過,要先刪除;如果你工程中存在一些不能確定版本的包,那麼生成的go.mod檔案可能就不完整,因此繼續執行下面的命令;
  • 執行go mod tidy命令,它會新增缺失的模組以及移除不需要的模組
  • 執行後會生成go.sum檔案(模組下載條目)。新增引數-v,例如go mod tidy -v可以將執行的資訊,即刪除和新增的包列印到命令列;
  • 執行命令go mod verify來檢查當前模組的依賴是否全部下載下來,是否下載下來被修改過。如果所有的模組都沒有被修改過,那麼執行這條命令之後,會列印all modules verified
  • 執行命令go mod vendor生成vendor資料夾,該資料夾下將會放置你go.mod檔案描述的依賴包,資料夾下同時還有一個檔案modules.txt,它是你整個工程的所有模組。在執行這條命令之前,如果你工程之前有vendor目錄,應該先進行刪除。同理go mod vendor -v會將新增到vendor中的模組打印出來;

總結

到此這篇關於詳解Go module的介紹及使用的文章就介紹到這了,更多相關Go module使用內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!