Go依赖管理 | 青训营笔记

130 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 3 天

依赖管理的意义

如果我们想要在研发一下项目时,我们应该学会站在巨人的肩膀上,我们没有精力去基于标准库从0到1的去搭建,更好的也是更现实的方法就是去使用第三方库,而这也是我们去学习依赖管理的原因。

GOPATH

Go1.5版本之后开始支持,能够控制Go语言程序编译时依赖包搜索路径的优先级。

例如查找项目的某个依赖包,首先会在项目根目录下的vender文件夹中查找,如果没有找到就会去$GOAPTH/src目录下查找。

GoVender的缺点

无法控制依赖的版本,更新项目又有可能出现项目冲突。

go module

简单来说,Go Modules是语义化版本管理的依赖项的包管理工具;它解决了GOPATH存在的缺陷,最重要的是,它是Go官方出品。(以下内容将会涉及到标准依赖项管理和构建)

创建Modules

首先创建一个可以供其他项目使用的项目:testmod,内容如下:

package testmod

import (
    "fmt"
)

func Hi(name string) string {
    return fmt.Sprintf("Hi, %s", name)
}

使用如下方式创建modules:
go mod init github.com/robteix/testmod 该命令会在目录下生成go.mod文件,内容如下:

module github.com/robteix/testmod

go 1.13

在将代码推送至Github之后,其他人可以使用如下命令下载到testmod:

go get github.com/robteix/testmod

默认情况下,go get将会下载到testmodmaster分支(在没有tags的情况下),即代码主分支。上面我们说过,Go Modules具有语义化版本管理功能的,所以可以使用go get下载特定版本的包:

go get github.com/robteix/testmod@vX.X.X

GOPROXY

我们可以通过GOPROXY来控制代理,以及通过GOPRIVATE控制私有库不走代理。

  • 设置GOPROXY代理:
go env -w GOPROXY=https://goproxy.cn,direct
  • 设置GOPRIVATE来跳过私有库,比如常用的Gitlab或Gitee,中间使用逗号分隔:
go env -w GOPRIVATE=*.gitlab.com,*.gitee.com
  • 如果在运行go mod vendor时,提示Get sum.golang.org/lookup/xxxx…: dial tcp 216.58.200.49:443: i/o timeout,则是因为Go 1.13设置了默认的GOSUMDB=sum.golang.org,这个网站是被墙了的,用于验证包的有效性,可以通过如下命令关闭:
go env -w GOSUMDB=off

私有仓库自动忽略验证

  • 可以设置 GOSUMDB="sum.golang.google.cn", 这个是专门为国内提供的sum 验证服务。
go env -w GOSUMDB="sum.golang.google.cn"
  • -w 标记 要求一个或多个形式为 NAME=VALUE 的参数, 并且覆盖默认的设置

GO mod

Go.mod是Golang1.11版本新引入的官方包管理工具用于解决之前没有地方记录依赖包具体版本的问题,方便依赖包的管理。

Go.mod其实就是一个Modules,关于Modules的官方定义为:

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

Modules和传统的GOPATH不同,不需要包含例如src,bin这样的子目录,一个源代码目录甚至是空目录都可以作为Modules,只要其中包含有go.mod文件。