Go语言的依赖管理
第五章 Go语言的依赖管理
5.1 依赖管理
- 依赖的概念:编译程序不可能所有东西都自己写,我们会大量使用一些第三方的库来引入自己的代码。
- 依赖管理的三个阶段:GOPATH、GOVENDOR、go mod
5.2 GOPATH和GOVENDOR工作模式
5.2.1 GOPATH工作模式
GOPATH工作模式就是把所有依赖包都放在GOPATH下的src中。
GOPATH依赖管理时依赖所在的目录位置:
此工作模式系统会去GOPATH和GOROOT中寻找引入的第三方库。
GOPATH工作模式的弊端:
- 无版本控制概念
- 无法同步一致第三方版本号
- 无法指定当前项目引用的第三方版本号
5.2.2 GOVENDOR工作模式
GOPATH工作模式有一个问题,当src下存在多个项目时,不同项目是由不同的人编写,在编写时所采用的依赖包版本可能不同,这时GOVENDOR工作模式解决了这个问题。
GOVENDOR工作模式是指在每个项目下创建vendor文件夹用来存放不同版本的依赖包,这样每个项目都会使用自己vendor下的依赖包,就解决了每个项目使用的依赖包版本不同的问题。
示例:
GOPATH下的src文件下有project1和project2两个项目,同时还有含有依赖包zap的go.uber.org目录
但这两个项目使用的依赖包版本不一样,此时在两个项目下各自创建vendor文件夹,把各自使用的不同版本的依赖包放入其中即可:
GOVENDOR工作模式依赖所在的目录位置:
可以看出系统会去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解决了什么问题?
- Go语言长久以来的依赖管理问题
- “淘汰”现有的GOPATH使用模式
- 统一社区中的其他的依赖管理工具(提供迁移功能)
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本身。
总览:
go mod依赖管理方式依赖所在的目录位置:
【小结】go mod依赖管理方式
- 由go命令统一管理,用户不必关心目录结构
- 初始化:go mod init
- 增加依赖:go get,或者直接在程序中写代码import
- 更新依赖:go get [@v...](不加版本号就默认是最新的版本),go mod tidy用来整理去除多余的依赖
- 将项目迁移到go mod:go mod init,go build ./...
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能
· 什么是nginx的强缓存和协商缓存
· 一文读懂知识蒸馏