go module包管理

發展史

Go 的包管理方式是逐漸演進的,在之前,不管是內部依賴還是外部依賴,所有的依賴的包都是放在GOPATH中, 所引發的問題是:

  • 在引用時候如果依賴包做了修改,刪除,外部更新,可能引入破壞性的錯誤。
  • 在生產環境中,也可能出現與測試環境運行不一致的問題。
  • 多個應用引用不同版本的包依賴也可能出問題。

針對上述問題,從1.5開始go提供了新特性Vendor,基本思路是將包放在當前工程的vendor目錄下面,在編譯的時候就會優先從vendor目錄下尋找依賴包。你細品,每個人工作的語言環境千變萬化,現在在項目中統一使用某個版本依賴包,是不是很香?不用再苦惱下載什麼版本的包。其實,vendor新特性,依然是有利有弊,問題:

  • 依然無法對外部依賴包做到很好的版本控制,會給包的升級產生很大的問題,無法評估升級帶來的風險。
  • 導致拷貝氾濫,某個包在不同的項目中各有一份copy,而且其版本可能不一樣;當依賴的包比較多的時候,vendor目錄也會非常龐大。

包管理是判定一門語言是否強大重要的因素。喜大普奔,從Go1.11開始加入了Go Module作為帶有版本控制新的包管理形式。

環境配置

在設置Go Module之前,需要先設置下環境變量: GO111MODULE設置

  • GO111MODULE=off,go命令行將不會支持module功能,尋找依賴包的方式將會沿用舊版本那種通過vendor目錄或者GOPATH模式來查找。
  • GO111MODULE=on,go命令行會使用modules,不會去GOPATH目錄下查找。
  • GO111MODULE=auto,默認值,go命令行將會根據當前目錄是否包含go.mod來決定是否啟用 Go modules。

開啟方式:

<code>go env -w GO111MODULE=on/<code>

代理設置 go可以設置國內代理地址去快速下載依賴包

  • https://goproxy.cn
  • https://goproxy.io
  • https://mirrors.aliyun.com/goproxy/

設置方式

<code>go env -w GOPROXY=https://goproxy.cn,direct/<code>

創建一個新模塊

本文在GOPATH目錄外創建mygin項目,以導入外部依賴和內部依賴進行演示,實際上go mod兼容了GOPATH目錄內的使用。

使用go mod int {模塊路徑}進行初始化,生成go.mod文件。

<code>go mod init hank.com/mygin /<code>

可以看到mygin目錄下生成了go.mod文件

<code>module hank.com/mygin

go 1.14/<code>

外部依賴很簡單,直接寫入路徑即可。如果要導入的是內部依賴,那麼就是直接go mod init初始化時的模塊路徑+包名

mygin

├── apis

│└── apis.go

└── main.go


apis.go

<code>package apis

import "github.com/gin-gonic/gin"

func Ping(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
}/<code>

main.go

<code>package main

import (
"github.com/gin-gonic/gin"
"hank.com/mygin/apis" //內部依賴
)

func main() {
r := gin.Default()
r.GET("/ping",apis.Ping)
r.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
}/<code>

初始化完成之後,只要執行go 構建命令,go test、go build、go run,就可以自動添加新的依賴關係。

<code>go run main.go

go: finding module for package github.com/gin-gonic/gin
go: downloading github.com/gin-gonic/gin v1.6.2
go: found github.com/gin-gonic/gin in github.com/gin-gonic/gin v1.6.2
go: downloading github.com/mattn/go-isatty v0.0.12
go: downloading gopkg.in/yaml.v2 v2.2.8
go: downloading github.com/gin-contrib/sse v0.1.0
go: downloading github.com/go-playground/validator/v10 v10.2.0
go: downloading github.com/golang/protobuf v1.3.3
go: downloading github.com/ugorji/go v1.1.7
go: downloading github.com/leodido/go-urn v1.2.0
go: downloading github.com/go-playground/universal-translator v0.17.0
go: downloading github.com/ugorji/go/codec v1.1.7
go: downloading github.com/go-playground/locales v0.13.0
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached./<code>

這時候我們在來看看go.mod文件,多了導入外部依賴包的路徑,還帶上版本的信息,而內部依賴是不需要寫入的。

<code>module hank.com/mygin

go 1.14

require github.com/gin-gonic/gin v1.6.2 // indirect/<code>

go.mod 是啟用了 Go moduels 的項目所必須的最重要的文件,它描述了當前項目(也就是當前模塊)的元信息,每一行都以一個動詞開頭,目前有以下 5 個動詞:

  • module:用於定義當前項目的模塊路徑。
  • go:用於設置預期的 Go 版本。
  • require:用於設置一個特定的模塊版本。
  • exclude:用於從使用中排除一個特定的模塊版本。
  • replace:用於將一個模塊版本替換為另外一個模塊版本。

注意這時候下載的依賴包不再GOPATH目錄下,而是放在src/pkg/mod目錄下:

go module包管理

除了go mod文件,再目錄下還會生成go sum文件,加密hash,防止被惡意篡改。

升級依賴

go get升級

<code>go get github.com/gin-gonic/gin/<code>

go get 默認值為@latest,會自動升級最新穩定版本的依賴包,除此之外go get還有多種方式:

<code>//指定版本
go get github.com/gin-gonic/[email protected]
//指定分支
go get github.com/gin-gonic/gin@master
//指定git commit id
go get github.com/gin-gonic/gin@e3702bed2/<code>

刪除未使用的依賴

<code>go mod tidy/<code>

其他常用命令

go list -m all查看所有依賴包 添加一個依賴有可能帶來其他依賴包的引入,查看所有依賴包選項:

<code>$ go list -m all

hank.com/mygin
github.com/davecgh/go-spew v1.1.1
github.com/gin-contrib/sse v0.1.0
github.com/gin-gonic/gin v1.6.2
github.com/go-playground/assert/v2 v2.0.1

github.com/go-playground/locales v0.13.0
github.com/go-playground/universal-translator v0.17.0
github.com/go-playground/validator/v10 v10.2.0
github.com/golang/protobuf v1.3.3
github.com/google/gofuzz v1.0.0
github.com/json-iterator/go v1.1.9
github.com/leodido/go-urn v1.2.0
github.com/mattn/go-isatty v0.0.12
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742
github.com/pmezard/go-difflib v1.0.0
github.com/stretchr/objx v0.1.0
github.com/stretchr/testify v1.4.0
github.com/ugorji/go v1.1.7
github.com/ugorji/go/codec v1.1.7
golang.org/x/sys v0.0.0-20200116001909-b77594299b42
golang.org/x/text v0.3.2
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405
gopkg.in/yaml.v2 v2.2.8/<code>

go list -m -versions列出依賴包可用的版本

<code>go list -m -versions github.com/gin-gonic/gin

github.com/gin-gonic/gin v1.1.1 v1.1.2 v1.1.3 v1.1.4 v1.3.0 v1.4.0 v1.5.0 v1.6.0 v1.6.1 v1.6.2/<code>


分享到:


相關文章: