go mod 与 goproxy 的使用

3,635 阅读5分钟


go modules 是 golang 1.11 新加的特性,Modules官方定义为:

模块是相关Go包的集合。modules是源代码交换和版本控制的单元。go命令直接支持使用modules,
包括记录和解析对其他模块的依赖性。modules替换旧的基于GOPATH的方法来指定在给定构建中使用
哪些源文件。

使用

  • 把 golang 升级到 1.11(现在1.12 已经发布了,建议使用1.12)

  • 设置 GO111MODULE

GO111MODULE

GO111MODULE 有三个值:off, on和auto(默认值)

  • GO111MODULE=off,go命令行将不会支持module功能,寻找依赖包的方式将会沿用旧版本那种通过vendor目录或者GOPATH模式来查找。

  • GO111MODULE=on,go命令行会使用modules,而一点也不会去GOPATH目录和vendor文件夹下查找,只会根据go.mod下载依赖。

  • GO111MODULE=auto,默认值,go命令行将会根据当前目录来决定是否启用module功能。这种情况下可以分为两种情形:

1. 当前目录在GOPATH/src之外且该目录包含go.mod文件。

2. 当前文件在包含go.mod文件的目录下面。

当modules 功能启用时,依赖包的存放位置变更为$GOPATH/pkg,允许同一个package多个版本并存,且多个项目可以共享缓存的 module。

go mod

golang 提供了 go mod命令来管理包。

go mod 有以下命令:

命令说明
downloaddownload modules to local cache(下载依赖包)
editedit go.mod from tools or scripts(编辑go.mod
graphprint module requirement graph (打印模块依赖图)
initinitialize new module in current directory(在当前目录初始化mod)
tidyadd missing and remove unused modules(拉取缺少的模块,移除不用的模块)
vendormake vendored copy of dependencies(将依赖复制到vendor下)
verifyverify dependencies have expected content (验证依赖是否正确)
whyexplain why packages or modules are needed(解释为什么需要依赖)


goproxy

关于goproxy,简单来说就是一个代理,让我们更方便的下载哪些由于墙的原因而导致无法下载的第三方包,比如golang.org/x/下的包,虽然也有各种方法解决,但是,如果是你在拉取第三方包的时候,而这个包又依赖于golang.org/x/下的包,你本地又恰恰没有,当然不嫌麻烦的话,也可以先拉取golang.org/x/下的包,再拉取第三方包。

这个goproxy强大地方就在于代理,而它官网是这样介绍自己的【A Global Proxy for Go Modules】,就是这么强大,全球代理,让世界没有难下的包。

首先要将 GO111MODULE=on 与 GOPROXY=https://goproxy.io 写入到 /etc/profile 里面,之后 source /etc/profile 重新载入环境变量。

go.mod 和 go.sum介绍

go.mod是Go项目的依赖描述文件,该文件主要用来描述两个事情:

  1. 当前项目名(module)是什么。每个项目都应该设置一个名称,当前项目中的包(package)可以使用该名称进行相互调用。

  2. 当前项目依赖的第三方包名称。项目运行时会自动分析项目中的代码依赖,生成go.sum依赖分析结果,随后go编译器会去下载这些第三方包,然后再编译运行。

go.sum依赖分析文件,记录每个依赖库的版本和哈希值

一般情况下,go.sum应当被添加到版本管理中随着go.mod文件一起提交。

使用案例

1. 在GOPATH 目录之外新建一个目录,并使用go mod init 初始化生成go.mod 文件。go.mod文件一旦创建后,它的内容将会被go toolchain全面掌控。go toolchain会在各类命令执行时,比如go get、go build、go mod等修改和维护go.mod文件。

2. go.mod 提供了module, requirereplaceexclude 四个命令

(1) module 语句指定包的名字(路径)

(2) require 语句指定的依赖项模块

(3) replace 语句可以替换依赖项模块

(4) exclude 语句可以忽略依赖项模块

3. 新建一个 server.go 文件,写入以下代码:

package main

import (  
    "net/http"
    "github.com/labstack/echo"
)

func main() {
    e := echo.New()  
    e.GET("/", func(c echo.Context) error {    
        return c.String(http.StatusOK, "Hello, World!")  })  
    e.Logger.Fatal(e.Start(":1323"))
}

4. 执行 go run server.go 运行代码会发现 go mod 会自动查找依赖自动下载:

5. 在浏览器中打开

6. 查看go.mod 内容:

go module 安装 package 的原则是先拉最新的 release tag,若无tag则拉最新的commit,详见 Modules官方介绍。

7. go 会自动生成一个 go.sum 文件来记录 dependency tree: (省略一部分)

[root@localhost go]# cat go.sum
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/labstack/echo v3.3.10+incompatible h1:pGRcYk231ExFAyoAjAfD85kQzRJCRI8bbnE7CX5OEgg=
github.com/labstack/echo v3.3.10+incompatible/go.mod h1:0INS7j/VjnFxD4E2wkz67b8cVwCLbBmJyDaka6Cmk1s=
github.com/labstack/gommon v0.3.0 h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0=
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.9 h1:d5US/mDsogSGW37IV293h//ZFaeajb69h+EHFsv2xGg=

8. 再次运行 go run server.go 发现跳过了检查并安装依赖的步骤。

9.可以使用命令 go list -m -u all 来检查可以升级的package,使用go get -u need-upgrade-package 升级后会将新的依赖版本更新到go.mod * 也可以使用 go get -u 升级所有依赖

go get 升级

  • 运行 go get -u 将会升级到最新的次要版本或者修订版本(x.y.z, z是修订版本号, y是次要版本号)

  • 运行 go get -u=patch 将会升级到最新的修订版本

  • 运行 go get package@version 将会升级到指定的版本号version

  • 运行go get如果有版本的更改,那么go.mod文件也会更改

以上我们介绍了go mod 与 goproxy 的使用。

感谢阅读!


欢迎扫码关注公众号,更多精彩文章与您分享!