跳出Go module的泥潭

原文作者:smallnest

Go 1.11 前天已經正式發佈了,這個版本包含了兩個最重要的feature就是 moduleweb assembly。雖然也有一些簡單的教程介紹了go module的特性,但是基本上都是hello world的例子,在實踐的過程中, 很多人都在“拼命的掙扎”,包括我自己, 從一些qq羣、github的issue, twitter上都可以看到大家茫然或者抱怨的語句。

雖然有三個幫助文件go help modgo help modulesgo help module-get可以瞭解一些go module的用法,但是感覺Go開發組對module這一特性還是沒有很好的做一個全面的介紹,很多情況還得靠大家看源代碼或者去猜,比如module下載的文件夾、版本格式的完整聲明,module的最佳實踐等,並且當前Go 1.11的實現中還有一些bug,給大家在使用的過程中帶來了很大的困難。

我也在摸索中前行, 記錄了摸索過程中的一些總結,希望能給還在掙扎中的Gopher一些幫助。

Introduction to Go Modules 是一篇很好的go module 入門介紹, 如果你仔細閱讀了它,應該就不需要看本文了。

1、GO111MODULE

要使用go module,首先要設置GO111MODULE=on,這沒什麼可說的,如果沒設置,執行命令的時候會有提示,這個大家應該都瞭解了。

2、既有項目

假設你已經有了一個go 項目, 比如在$GOPATH/github.com/smallnest/rpcx下, 你可以使用go mod init github.com/smallnest/rpcx在這個文件夾下創建一個空的go.mod (只有第一行 module github.com/smallnest/rpcx)。

然後你可以通過 go get ./...讓它查找依賴,並記錄在go.mod文件中(你還可以指定 -tags,這樣可以把tags的依賴都查找到)。

通過go mod tidy也可以用來爲go.mod增加丟失的依賴,刪除不需要的依賴,但是我不確定它怎麼處理tags

執行上面的命令會把go.modlatest版本換成實際的最新的版本,並且會生成一個go.sum記錄每個依賴庫的版本和哈希值。

3、新的項目

你可以在GOPATH之外創建新的項目。

go mod init packagename可以創建一個空的go.mod,然後你可以在其中增加require github.com/smallnest/rpcx latest依賴,或者像上面一樣讓go自動發現和維護。

go mod download可以下載所需要的依賴,但是依賴並不是下載到$GOPATH中,而是$GOPATH/pkg/mod中,多個項目可以共享緩存的module。

4、go mod命令

1download    download modules to local cache (下載依賴的module到本地cache))
2edit        edit go.mod from tools or scripts (編輯go.mod文件)
3graph       print module requirement graph (打印模塊依賴圖))
4init        initialize new module in current directory (再當前文件夾下初始化一個新的module, 創建go.mod文件))
5tidy        add missing and remove unused modules (增加丟失的module,去掉未用的module)
6vendor      make vendored copy of dependencies (將依賴複製到vendor下)
7verify      verify dependencies have expected content (校驗依賴)
8why         explain why packages or modules are needed (解釋爲什麼需要依賴)

有些命令還有bug, 比如go mod download -dir:

1go mod download -dir /tmp
2flag provided but not defined: -dir
3usage: go mod download [-dir] [-json] [modules]
4Run 'go help mod download' for details.

幫助裏明明說可以設置dir,但是實際卻不支持dir參數。

看這些命令的幫助已經比較容易瞭解命令的功能。

5、翻牆

在國內訪問golang.org/x的各個包都需要翻牆,你可以在go.mod中使用replace替換成github上對應的庫。

1replace (
2    golang.org/x/crypto v0.0.0-20180820150726-614d502a4dac => github.com/golang/crypto v0.0.0-20180820150726-614d502a4dac
3    golang.org/x/net v0.0.0-20180821023952-922f4815f713 => github.com/golang/net v0.0.0-20180826012351-8a410e7b638d
4    golang.org/x/text v0.3.0 => github.com/golang/text v0.3.0
5)

依賴庫中的replace對你的主go.mod不起作用,比如github.com/smallnest/rpcxgo.mod已經增加了replace,但是你的go.mod雖然requirerpcx的庫,但是沒有設置replace的話, go get還是會訪問golang.org/x

所以如果想編譯那個項目,就在哪個項目中增加replace

6、版本格式

下面的版本都是合法的:

1gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7
2gopkg.in/vmihailenco/msgpack.v2 v2.9.1
3gopkg.in/yaml.v2 <=v2.2.1
4github.com/tatsushid/go-fastping v0.0.0-20160109021039-d7bb493dee3e
5latest

7、go get 升級

  • 運行 go get -u 將會升級到最新的次要版本或者修訂版本(x.y.z, z是修訂版本號, y是次要版本號)
  • 運行 go get -u=patch 將會升級到最新的修訂版本
  • 運行 go get package@version 將會升級到指定的版本號version

8、go mod vendor

go mod vendor 會複製modules下載到vendor中, 貌似只會下載你代碼中引用的庫,而不是go.mod中定義全部的module。

9、go module, vendor 和 Travis CI

https://arslan.io/2018/08/26/using-go-modules-with-vendor-support-on-travis-ci/


版權申明:內容來源網絡,版權歸原創者所有。除非無法確認,我們都會標明作者及出處,如有侵權煩請告知,我們會立即刪除並表示歉意。謝謝。

Golang語言社區

ID:Golangweb

www.bytedancing.com

遊戲服務器架構丨分佈式技術丨大數據丨遊戲算法學習

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章