Go语言的依赖管理

第五章 Go语言的依赖管理

5.1 依赖管理

  • 依赖的概念:编译程序不可能所有东西都自己写,我们会大量使用一些第三方的库来引入自己的代码。
  • 依赖管理的三个阶段:GOPATH、GOVENDOR、go mod

5.2 GOPATH和GOVENDOR工作模式

5.2.1 GOPATH工作模式

GOPATH工作模式就是把所有依赖包都放在GOPATH下的src中。

GOPATH依赖管理时依赖所在的目录位置:

image

此工作模式系统会去GOPATH和GOROOT中寻找引入的第三方库。

GOPATH工作模式的弊端:

  1. 无版本控制概念
  2. 无法同步一致第三方版本号
  3. 无法指定当前项目引用的第三方版本号

5.2.2 GOVENDOR工作模式

GOPATH工作模式有一个问题,当src下存在多个项目时,不同项目是由不同的人编写,在编写时所采用的依赖包版本可能不同,这时GOVENDOR工作模式解决了这个问题。

GOVENDOR工作模式是指在每个项目下创建vendor文件夹用来存放不同版本的依赖包,这样每个项目都会使用自己vendor下的依赖包,就解决了每个项目使用的依赖包版本不同的问题。

示例:

GOPATH下的src文件下有project1和project2两个项目,同时还有含有依赖包zap的go.uber.org目录

image

但这两个项目使用的依赖包版本不一样,此时在两个项目下各自创建vendor文件夹,把各自使用的不同版本的依赖包放入其中即可:

image

GOVENDOR工作模式依赖所在的目录位置:

image

可以看出系统会去vendor目录中去寻找依赖。

此工作模式系统会去项目目录下的vendor、GOPATH、GOROOT中寻找引入的第三方库。

【小结】GOVENDOR

  • 每个项目都有自己的vendor目录用来存放第三方库
  • 因此诞生了很多第三方依赖管理工具用来对每个项目的vendor目录进行管理,如glide、dep、go dep...

5.3 go mod的使用

  • 什么是Go Modules?

Go modules是Go语言的依赖解决方案,发布于Go1.11,成长于Go1.12,丰富于Go1.13,正式于Go1.14推荐在生产上使用。

  • Go Modules解决了什么问题?
  1. Go语言长久以来的依赖管理问题
  2. “淘汰”现有的GOPATH使用模式
  3. 统一社区中的其他的依赖管理工具(提供迁移功能)

5.3.1 go mod命令

命令 作用
go mod init 生成go.mod文件
go mod download 下载go.mod文件中指明的所有依赖
go mod tidy 整理现有的依赖
go mod graph 查看现有的依赖结构
go mod edit 编辑go.mod文件
go mod vendor 导出项目所有的依赖到vendor目录
go mod verify 校验一个模块是否被篡改过
go mod why 查看为什么需要依赖某模块

5.3.2 go mod环境变量

GO111MODULE和GOPROXY为常用环境变量。

环境变量可以通过go env命令来进行查看

$ go env
GO111MODULE="auto"
GOPROXY="http://proxy.golang.org,direct"
GONOPROXY=""
GOSUMDB="sum.golang.org"
GONOSUMDB=""
GOPRIVATE=""
...

5.3.2.1 GO111MODULE

Go语言提供了GO111MODULE这个环境变量来作为Go Modules的开关,其允许设置以下参数:

  • auto:只要项目包含了go.mod文件的话启用Go Modules,目前在Go1.11至Go1.14仍是默认值。
  • on:启用Go Modules,推荐设置,将会是未来版本中的默认值。
  • off:禁用Go Modules,不推荐设置。

设置GO111MODULE状态命令行:

$ go env -w GO111MODULE=on

5.3.2.2 GOPROXY

这个环境变量主要是用于设置Go模块代理(Go module proxy),其作用是用于使Go在后续拉取模块版本时直接通过镜像站点来快速拉取。用来设置从哪个第三方托管平台下载依赖包,设置好后可以通过import来设置路径,可以自动去下载依赖包。

GOPROXY的默认值是:http://proxy.golang.org,direct

proxy.golang.org国内访问不了,需要设置国内的代理。

  • 阿里云

http://mirrors.aliyun.com/goproxy/

  • 七牛云

http://goproxy.cn,direct

如:

$ go env -w GOPROXYU=http://goproxy.cn,direct

GOPROXY的值是一个以英文逗号“ , ”分割的Go模块代理列表,允许设置多个模块代理,假设你不想使用,也可以将其设置为“ off ”,这将会禁止Go在后续操作中使用任何Go模块代理。

如:

$ go env -w GOPROXYU=http://goproxy.cn,http://mirrors.aliyun.com/goproxy/,direct

direct

而在刚刚设置的值中,我们可以发现值列表中有“direct”标识,它又有什么作用呢?

实际上“direct”是一个特殊指示符,用于指示Go回源到模块版本的源地址去抓取(比如GitHub等),场景如下:当值列表中上一个Go模块代理返回404或410错误时,Go自动尝试列表中的下一个,遇见“direct”时回源,也就是回到源地址去抓取,而遇见EOF时终止并抛出类似“invalid version: unknowrevision...”的错误。

5.3.2.3 GOSUMDB

它的值是一个GO checksum database,用于在拉取模块版本时(无论是从源站拉去还是通过Go module proxy拉取)保证拉取到的模块版本数据未经过篡改,若发现不一致,也就是可能存在篡改,将会立即终止。

GOSUMDB的默认值为:sum.golang.org,在国内也是无法访问的,但是GOSUMDB可以被Go模块代理所代理(详见:Proxying a Checksum Database)。

因此我们可以通过设置GOPROXY来解决,而先前我们所设置的模块代理goproxy.cn就能支持代理sum.golang.org,所以这一个问在设置GOPROXY后,你可以不需要过度关心。

另外若对GOSUMDB的值有自定义需求,其支持如下格式:

  • 格式1:<SUMDB_NAME>+<PUBLIC_KEY>
  • 格式2:<SUMDB_NAME>+<PUBLIC_KEY><SUMDB_URL>

也可以将其设置为“off”,也就是禁止Go在后续操作中校验模块版本。

5.3.2.4 GONOPROXY/GONOSUMDB/GOPRIVATE

这三个环境变量都是用在当前项目依赖了私有模块,例如像是你公司的私有git仓库,又或是github中的私有库,都是属于私有模块,都是要进行设置的,否则会拉取失败。

更细致来讲,就是依赖了由GOPROXY指定的Go模块代理或由GOSUMDB指定Go checksum database都无法访问到的模块的场景。

如果一个项目是私有项目,可以设置其为GOPRIVATE,表示其不会再通过GOPROXY下载和校验。

而一般建议直接设置GOPRIVATE,它的值将作为GONOPROXY和GONOSUMDB的默认值。

并且它们的值都是一个以英文逗号“ , ”分割的模块路径前缀,也就是可以设置多个,例如:

$ go env -w GOPRIVATE="git.example.com,github.com/eddycjy/mquote"

设置后,前缀为git.xxx.com和github.com/eddycjy/mquote的模块都会被认为是私有模块。

如果不想每次都重新设置,我们也可以利用通配符,例如:

$ go env -w GOPRIVATE="*.example.com"

这样设置的话,所有模块路径为example.com的子域名(例如:git.example.com)都将不经过Go module proxy和Go checksum database,需要注意的是不包括example.com本身。

总览:

image

go mod依赖管理方式依赖所在的目录位置:

image

【小结】go mod依赖管理方式

  • 由go命令统一管理,用户不必关心目录结构
  • 初始化:go mod init
  • 增加依赖:go get,或者直接在程序中写代码import
  • 更新依赖:go get [@v...](不加版本号就默认是最新的版本),go mod tidy用来整理去除多余的依赖
  • 将项目迁移到go mod:go mod init,go build ./...
posted @   雪碧锅仔饭  阅读(511)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能
· 什么是nginx的强缓存和协商缓存
· 一文读懂知识蒸馏
点击右上角即可分享
微信分享提示