【環境篇】go mod--讓人又愛又恨的包管理工具

封面.png

爲何咱們須要包管理

Python有pip,Nodejs有npm。是否是別的語言有包管理工具,因此go就要有?固然不是,來看看下面這段代碼:git

import (
    "github.com/TomatoMr/something"
)

這是go引用包的方式,很明顯這是個第三方包,那麼它在咱們本機上具體是怎麼被找到的呢?
先說說尚未go mod的時候,它是這麼找的:github

  1. 項目根目錄下有vendor,那就在vendor下找;
  2. vendor找不到包就往GOROOT、$GOPATH找;
  3. 以上都找不到,就去網上找,好比"github.com/TomatoMr/something",那就去GitHub上找。

找到包以後就會將它下載到GOPATH下,簡單易懂。但這不足夠,好比當我對這些包有了版本控制的需求,那這個包管理方式還有所欠缺,具體場景以下:golang

GitHub-1.png

我引用的第三包有不一樣的版本,若是我不用其餘的包管理工具,那麼我默認得到的包是最新版,也就是v0.0.2的版本,而這時的版本的Hi()方法已經不存在了,而個人代碼裏面仍然調用了Hi()方法,這就會使個人代碼報錯,我如今須要有版本控制的包管理工具。shell

error.png

go mod來了

在go的1.11版本以後,go mod就被指定爲親生的包管理工具,它提供了更加靈活的管理辦法,能夠對包進行版本控制,並且你的項目也不須要必定放在GOPATH下了(放GOPATH下也沒啥很差)。看看它是具體怎麼作的:npm

$ go mod init <module_name> # 對一個項目的module進行初始化,module_name是選填的,能夠在初始化的時候就制定module名
$ go mod tidy # 添加包,清除沒有引用的包

gomod-1.png

執行完兩句命令以後,你會看到,項目下多了go.mod和go.sum文件。緩存

go.mod: 能夠理解爲包管理文件
go.sum: 能夠理解爲包的版本控制文件服務器

好了,咱們如今來看看,咱們前面的需求,我想要引入包的時候可以選擇版本,用gomod怎麼作。咱們先將go.mod文件中的版本號改成:v0.0.1。ide

gomod-2.png

再在項目根目錄執行工具

$ go mod tidy

咱們能夠看到go.sum文件也相應地改變了。學習

gomod-3.png

再看看咱們的代碼,調用Hi()方法沒有報錯了。

gomod-4.png

掌握go mod的一些基本知識

1.須要學習什麼是go mod

Go mod provides access to operations on modules.

Note that support for modules is built into all the go commands,
not just 'go mod'. For example, day-to-day adding, removing, upgrading,
and downgrading of dependencies should be done using 'go get'.
See 'go help modules' for an overview of module functionality.

Usage:

        go mod <command> [arguments]

The commands are:

        download    download modules to local cache # 下載包
        edit        edit go.mod from tools or scripts # 修改或替換包
        graph       print module requirement graph # 打印依賴關係
        init        initialize new module in current directory # 初始化項目
        tidy        add missing and remove unused modules # 更新依賴包
        vendor      make vendored copy of dependencies # 複製依賴包到vendor
        verify      verify dependencies have expected content # 檢查依賴是否正確
        why         explain why packages or modules are needed # 解釋爲何須要包或模塊,應該說是那些模塊會調用到那些依賴包和模塊

Use "go help mod <command>" for more information about a command.

使用go mod以後,包下載以後是放在了$GOPATH/pkg/mod下:

gomod-5.png

2.有些環境變量應該知道

GO111MODULE=
# 默認當項目中有go.mod文件就用go mod管理,沒有就仍是舊的方式,GO111MODULE=on強制使用go mod,GO111MODULE=off關閉go mod
GOPROXY="https://goproxy.cn,https://proxy.golang.org,https://goproxy.io,direct"
# GOPROXY設置代理,我建議設置成與我上面一致,第一個地址是七牛雲的代理,防止被牆,direct值得是從源站下載
GOSUMDB="sum.golang.org"
# 指示校驗和服務器的地址和公鑰,這裏指"sum.golang.org"的公鑰可省略,若要關閉校驗,GOSUMDB=off。
GOPRIVATE=""
# GOPRIVATE表示私有倉庫。私有倉庫下的全部依賴一概從源站下載,並且不作校驗。
GONOPROXY=""
# 與GOPROXY對應
GONOSUMDB=""
# 與GOSUMDB對應

熟悉這幾個環境變量有實際的好處,好比由於某種不可描述的緣由而不能下載國外網站的包,又或者由於本身公司搭建了私有倉庫,須要作相應的配置。

3.使用replace替換包

有這樣一寫應用場景,好比說:

  1. 你要下載的包更名字了;
  2. 你引用了一個本地的包,這個包並無提交到倉庫裏;

這個時候就須要replace來替換包,以下:

package main

import (
    "github.com/TomatoMr/bar" # 在這個地址下面沒有這個包,多是原包換名字或者這是我一個本地包
    "github.com/TomatoMr/something"
)

func main()  {
    something.Hello()
    something.Hi()
    bar.HelloBar()
}

看看咱們在go.mod文件裏面應該怎麼修改:

module Foo

go 1.13

require (
    github.com/TomatoMr/something v0.0.1
)

replace github.com/TomatoMr/bar => D:\\share\\go\\src\\foo\\bar # 將bar這個包替換成個人本地路徑(絕對路徑或者相對路徑都可)

而後執行:

go mod tidy

接着go.mod發生了變化:

module Foo

go 1.13

require (
    github.com/TomatoMr/bar v0.0.0-00010101000000-000000000000
    github.com/TomatoMr/something v0.0.1
)

replace github.com/TomatoMr/bar => D:\\share\\go\\src\\foo\\bar

能夠看到github.com/TomatoMr/bar已經require進去了。

4.清除mod下載的包

go clean -modcache

這個比較少用,當你的環境被破壞,或者想刪除全部的mod緩存的話,能夠這麼幹。


歡迎關注個人公衆號:onepunchgo,會整理相關的文檔和資料。

image

相關文章
相關標籤/搜索