go modules 的一些细节

362 阅读3分钟

前言

在一些Java的项目中,有 Maven等这些版本管理工具,可以很好的管理各种版本依赖关系,但是在 Golang 的项目中,之前官方并没有提供版本管理工具,以前都是用 go get 进行安装, 随着项目的变大, 就处理这种依赖关系就变得很麻烦。原文

如果你对 Go 感兴趣, 可以关注我的公众号: GoGuider

vendor 机制

为了解决版本依赖问题, 官方出了一个 vendor 机制,将项目依赖的包都放在该目录中,但这也并没有很好地管理依赖的版本。

因为vendor 机制有几个大的问题:

1、需要将外部库放到项目中, 导致项目体积变得很大
2、项目版本很难指定和控制

go dep 和 go modules

之后官方出了一个准官方版本管理工具 go dep,这也算是 go modules 的前身了吧。随着 Go1.11 的发布,Golang 给我们带来了 module 全新特性,这是 Golang 新的一套依赖管理系统。在 Go1.12发布后,go modules 进一步稳定,但官方还是没有将其设为默认机制,所以踩坑之路是必须的,本篇文章除了详细说明 go modules 的特性以及使用之外,还总结了我在这个过程中遇到的一些“坑”。

目前 go help modgo help modulesgo help module-get可以了解一些go module的用法, 不过有些用法还是介绍的不够详细, 需要我们进行猜; 所以今天整理了一篇文章和大家一起了解。

随着go1.12就要发布了。这是首个将go modules纳入正式支持的稳定版本。go modules引入go.mod, 我们可以更好的管理外部库以及版本了。

在go.mod中指定版本

在使用go get 如果我们想指定一些版本信息, 可以参照下面的操作:

go get github.com/mqu/go-notify@ef6f6f49

在go.mod文件中我们也需要这样指定, 目标库 带上指定版本, 这样可以安装时明确版本, 避免不避免的麻烦, 增加项目的确定性和安全性。

所以 在go.mod中也需要这样指定版本

module github.com/goguider/hello

go 1.12

require (
	cloud.google.com/go v0.37.1 // indirect
	github.com/PuerkitoBio/goquery v1.5.0
	github.com/araddon/dateparse v0.0.0-20190223010137-262228af701e
	github.com/b3log/gulu v0.0.0-20190806034141-2b1d1b33ff3d
	github.com/b3log/lute v0.0.0-20190922061740-a6de76dabec1
	github.com/beevik/etree v1.1.0 // indirect
	github.com/bluele/gcache v0.0.0-20190301044115-79ae3b2d8680
	...
)

go modules 发布之后,就完全统一了包引用的地址,如上面我们说的创建 go.mod 文件后, 使用初始化内容的第一行就是我们说的项目依赖路径,通常来说该地址就是项目的仓库地址,所有需要引用项目包的地址都填写这个地址,无论是内部之间引用还是外部引用

go mod 相关命令

download    download modules to local cache (下载依赖的module到本地cache))
edit        edit go.mod from tools or scripts (编辑go.mod文件)
graph       print module requirement graph (打印模块依赖图))
init        initialize new module in current directory (再当前文件夹下初始化一个新的module, 创建go.mod文件))
tidy        add missing and remove unused modules (增加丢失的module,去掉未用的module)
vendor      make vendored copy of dependencies (将依赖复制到vendor下)
verify      verify dependencies have expected content (校验依赖)
why         explain why packages or modules are needed (解释为什么需要依赖)

最后会有一个go.sum文件

每一个引入库, 后面都有一个唯一标记, 用来控制版本, 也就是版本号 + 时间戳 +hash。

如果你对Go也感兴趣, 可以关注我的公众号