一、为什么需要包管理?

在开发中一个很现实的问题,如果你开发一个项目里面会用到 Redis,于是你写了一套与 Redis的驱动和数据交互模块。

然后另一个新项目启动了,你再次需要用到 Redis,此时你会怎么办?

有些人会说,直接复制过去就好了,是的你可以这样做。

现在问题又来了,某一天你发现你的这个模块里面有一个 Bug 需要修复,但是这个模块你已经在20个项目里面投入了使用,此时你该怎么办?

如果按照刚才的那种,把写好的模块不停的复制粘贴到新项目里面,你或许只能挨个项目去改了。

为了解决这个问题大佬们就想出了包管理这个概念,就是把一些常用的或者很好的模块进行统一存放,统一管理。

你如果要使用到某个模块时,你只需要配置下就能帮你把这个模块导入到你的项目里面,同时带有版本号,这样你更新模块后提交到库里面,使用到的模块只需要修改下版本号就自动更新了。

这样做的好处有很多,就不一一列举了。

当然这不是 GoLang 里面特有的东西,像Java里面有Maven,PHP里面有composer,都是用于包管理的工具。

二、GoMod的诞生前的尬点

虽然说 GoLang 最厉害的是一套代码能编译出不同环境的二进制包,还有高并发等。

但如果你接触 GoLang 比较早的话,就应该知道早期的 GoLang 开发项目只能在它特定的目录下面建工程进行开发,那感觉之难受,稍有不慎就找不到包。

这就是最早期的包管理 GOPATH。

你想所有的工程都要放在同一个指定目录下面,那在包管理上面就很难对每一个项目的包管理进行单独管理,并且早期根本没有包管理的配置文件,所有包都用 go get 拉去到本地。

于是你在迁移工程时就会经常发现少包。

为了解决这个问题,后续官方在迭代到1.5版本之后,提供了一个 GO15VENDOREXPERIMENT 环境变量,他支持除从GOPATH下面检索包依赖之外,还支持项目根目录下的 vendor 目录下检索,但是依旧没有这个项目的包依赖配置文件支持。

但是很快就有大牛开发出了 govendor,它解决了什么问题呢?

它好好利用了1.5的特性,在此基础上新增了项目依赖配置文件,以及包管理的常用指令。

常用指令清单

大家都以为这个包管理工具会被官方采纳的,但是官方一直不发话。

就这样到了GoLang 1.11版本,官方突然宣布引入 Go modules(后面坚持 GoMod)进行包管理。

GoMod的诞生把之前在包管理上的难题,以及要在指定位置新建项目的尬点都解决了。

从此你可以在任意位置新建你的项目,只需要在你的 GoMod 的配置文件里面做好配置就行。

同时也不会在你的项目下面多一个vendor目录,当然你也可以同样把所有依赖导入到这个目录里面,但一般不会这么做,除非有一些特别的难言之隐。

这么强大的功能,又是官方指定的,有什么理由不用呢?

所以后续的文章只要是我原创的,如果需要用到包管理,都默认是GoMod。

三、快速入门教程

截止目前我写文章2021年08月21日,Go已经更新到1.17版了,所以应该不会有人还在使用比1.11之前的版本吧。

如果还有就请你升级下,至少大于等于1.11版。

如果你是大于1.11版本,安装完后就自带了这个功能,不需要额外安装任何依赖。

只需要在你的项目下面执行初始化命令:

go mod init github.com/kun

解释下这几参数是什么意思:

go mod init 模块名称

其中模块名称你可以随便写,但是后续工程里面的引入这个项目的包时你会发现和这个模块名有关,所以这里需要稍微慎重点取名字。

!https://s3-us-west-2.amazonaws.com/secure.notion-static.com/0c4c3107-c597-4c0d-b95c-ba838d6ba0db/Untitled.png

这里贴上常见命令列表:

GoMod常见命令

这里导入下 Gin 这个框架,命令如下:

go get github.com/gin-gonic/gin

然后你可以看到go.mod文件里面自动给加上好多内容如下:

!https://s3-us-west-2.amazonaws.com/secure.notion-static.com/7e90209a-4fbe-4a99-b4e2-795c6b348106/Untitled.png

同时还多了一个go.sum文件,这个文件不用管它我们一般不会关注他的存在。

注意:这里需要在项目的目录下面执行才会自动给你加到go.mod里面,你在别的目录下执行不会给你添加的。

现在gin这个框架就导入完毕了,你在项目里面就可以正常使用了。

!https://s3-us-west-2.amazonaws.com/secure.notion-static.com/7f59e8ce-23ae-4f44-9422-b0240fd09354/Untitled.png

四、答疑时间

问题一:依赖的包下载到哪里了?还在GOPATH里吗?

不在。

使用Go的包管理方式,依赖的第三方包被下载到了$GOPATH/pkg/mod路径下。

如果你成功运行了本例,可以在您的$GOPATH/pkg/mod 下找到一个这样的包 github.com/gin-gonic/gin@v1.7.4,感兴趣可以去看下。

问题二: 依赖包的版本是怎么控制的?

在上一个问题里,可以看到最终下载在$GOPATH/pkg/mod 下的包 github.com/gin-gonic/gin@v1.7.4 最后会有一个版本号 1.7.4,也就是说,$GOPATH/pkg/mod里可以保存相同包的不同版本。

版本是在go.mod中指定的,如果在go.mod中没有指定,go命令会自动下载代码中的依赖的最新版本,本例就是自动下载最新的版本。

标签: none

添加新评论