聊聊 Go 的包管理
0、包管理的历史
Golang 的包管理一直被大众所诟病的一个点,但是我们可以看到现在确实是在往好的方向进行发展。
下面是官方的包管理工具的发展历史:
在 1.5 版本之前,所有的依赖包都是存放在 GOPATH 下,没有版本控制。这个类似 Google 使用单一仓库来管理代码的方式。这种方式的最大的弊端就是无法实现包的多版本控制,比如项目 A 和项目 B 依赖于不同版本的 package,如果 package 没有做到完全的向前兼容,往往会导致一些问题。
1.5 版本推出了 vendor 机制。所谓 vendor 机制,就是每个项目的根目录下可以有一个 vendor 目录,里面存放了该项目的依赖的 package。go build 的时候会先去 vendor 目录查找依赖,如果没有找到会再去 GOPATH 目录下查找。
1.9 版本推出了实验性质的包管理工具 dep,这里把 dep 归结为 Golang 官方的包管理方式可能有一些不太准确。关于 dep 的争议颇多,比如为什么官方后来没有直接使用 dep 而是弄了一个新的 modules,具体细节这里不太方便展开。
1.11 版本推出 modules 机制,简称 mod,也就是本文要讨论的重点。modules 的原型其实是 vgo,关于 vgo,可以参考文章末尾的参考链接。 https://research.swtch.com/vgo
1、go mod 是什么?
go mod 是 Golang 1.11 版本引入的官方包(package)依赖管理工具,用于解决之前没有地方记录依赖包具体版本的问题,方便依赖包的管理。
之前 Golang 主要依靠 vendor 和 GOPATH 来管理依赖库,vendor 相对主流,但现在官方更提倡 go mod。
总结一下:
从 go 1.11 开始支持
可以不需要 gopath 存在
环境变量 GO111MODULE,默认为 auto
项目存在 go.mod 则使用 go module,否则使用 GOPATH 和 vendor 机制
2、依赖管理
为什么需要依赖?
我们想复用已有的工作成果。
将已有的工作成果加入我们项目中作为依赖存在太多的不确定性:
包 API 的变化;包内部行为变化;包的依赖会变化;包已经不存在或无法访问;包与包之间的不同依赖相互冲突等
随着软件开发规模的逐步增大,涉及到的外部依赖越来越多,手动管理的所有依赖愈发不可能。所以我们需要依赖管理,我们需要有个工具或者规范来描述和定义包与包之间的依赖关系,并自动化的去处理、解析和满足这些依赖。
3、基本使用
1)环境准备
Golang 版本:1.12.3。在 1.12 版本之前,使用 Go modules 之前需要环境变量 GO111MODULE:
2)初始化 go module 环境
3)下载依赖包
注意点:
如果 tag 对应内容有更新,需要删除 pkg 中的缓存内容。
go get、go run、go build 也会自动下载依赖
4)添加新依赖包
方法一:直接修改 go.mod,然后执行:go mod download
方法二:使用 go get packagename@v1.2.3,会自动更新 go.mod 文件
方法三:go run、go build 也会自动下载依赖
5)将依赖包下载到 vendor 目录
注意:只会下载对应版本的包文件,不会下载所有版本
4、总结
1)大部分场景 go mod init 和 go mod tidy 就够了
2)查看 $GOPATH/pkg/mod 里面的文件就知道了,mod 做了一件类似 maven 的事把所有包都打上了版本号,解决多版本问题困扰。
作者:架构精进之路,十年研发风雨路,大厂架构师,CSDN 博客专家,专注架构技术沉淀学习及分享,职业与认知升级,坚持分享接地气儿的干货文章,期待与你一起成长
关注并私信我回复“01”,送你一份程序员成长进阶大礼包,欢迎勾搭。
Thanks for reading!
版权声明: 本文为 InfoQ 作者【架构精进之路】的原创文章。
原文链接:【http://xie.infoq.cn/article/641f6d8632d99e6775e00bc5e】。文章转载请联系作者。
评论