未能获得项目引用的依赖项_go modules:使用mod管理项目依赖包,通过vendor一键分发编译包...

在go语言1.11版本之前,没有modules机制,所有软件包都在安装在$GOPATH/src目录下。不同项目如果引用了同一个软件包的不同版本,就会造成编译麻烦。修改$GOPATH变量是当时一种比较简单的解决方案。

从1.11版本开始,开始有了GO111MODULE变量。因为是自1.11版本支持的,所以名字中有“111”。依靠go语言最新的mod模块,可以将依赖包的不同版本都缓存至$GOPATH/pkg/mod目录下,各个项目通过go.mod文件各取合适的依赖包版本使用。

如果想实现一键分发编译包,通过go mod vendor指令,将依赖包从$GOPATH/pkg/mod目录拷贝至当前项目目录下的vendor目录中。将目录打包,直接分发即可,当然这限同类平台。

如果是不同平台,通过go.mod文件重新下载依赖即可。如果网络不稳定,还可以通过export GOPROXY=https://goproxy.io设置网络代理。

依赖包版本号格式

在理解mod的工作方式之前,需要先了解一下go语言软件我版本号的组成。

6c2d59dc8d8fe843bf441cc4e156eded.png
  • MAJOR 主版本号,如果有大的版本更新,这种更新往往导致 API 和之前版本不兼容,此时数字加1。

  • MINOR 次版本号,当你做了向下兼容的新 feature,将此版本号升1。

  • PATCH 修订版本号,当你做了向下兼容的修复 bug fix,将此数字加1。

GO111MODULE

对于模块https://github.com/kataras/iris引用,不应该直接引用master主库,如果主库变化了,源码可能无法与新版本兼容,导致源码编译不过。这是go modules解决的问题。

go modules 是 golang 1.11 新加的特性。

GO111MODULE 有三个值:off, on和auto(默认值)。

  • GO111MODULE=off,go命令行将不会支持module功能,寻找依赖包的方式将会沿用旧版本那种通过vendor目录或者GOPATH模式来查找。

  • GO111MODULE=on,go命令行会使用modules,而一点也不会去GOPATH目录下查

  • GO111MODULE=auto,默认值,自动性取决于上下文目录。go命令行将会根据当前目录来决定是否启用module功能。这种情况下可以分为两种情形:

    • 当前目录在GOPATH/src之外且该目录包含go.mod文件

    • 当前文件在包含go.mod文件的目录下面。

查看所有依赖包

go list -m all

查看包有哪些版本

go list -m -versions github.com/gin-gonic/gin

v1.1.1 v1.1.2 v1.1.3 v1.1.4 v1.3.0 v1.4.0 v1.5.0 v1.6.0 v1.6.1

版本可升可降,直接指定版本。

go get github.com/gin-gonic/gin@v1.3.0

go get github.com/gin-gonic/gin@v1.1.4

只需要在依赖包后面加上 @version 就可以了

如何更换版本?

只需要在依赖包后面加上 @version 就可以了

go get github.com/gin-gonic/gin@v1.1.4

go get github.com/gin-gonic/gin@v1.3.0

版本可升可降,直接指定版本。

使用go mod edit直接修改

使用 go mod 来进行版本的切换,这样就需要两个步骤了

go mod edit -require="github.com/gin-gonic/gin@v1.1.4"

go mod tidy:删除未使用的依赖项

go mod tidy

tidy 会自动清理掉不需要的依赖项,同时可以将依赖项更新到当前版本

go mod:查看所有指令

go mod

The commands are:
download download modules to local cache
edit edit go.mod from tools or scripts
graph print module requirement graph
init initialize new module in current directory
tidy add missing and remove unused modules
vendor make vendored copy of dependencies
verify verify dependencies have expected content
why explain why packages or modules are needed

只有当使用go mod vendor指令后,才会将当前所有依赖包拷贝至当前项目目录下。

有人说,mod虽好,但是费开发者的电脑磁盘,go mod拉取的软件包都会放在当前目录的pkg/mod目录下面,不像java的maven本地一个集中的目录。其实在go 1.13版本中,go mod下载依赖包目前是放在$GOPATH/pkg/mod目录下,所有项目是共享的。

只有当使用go mod vendor指令后,才会将当前所有依赖包拷贝至当前项目目录下。

项目依赖包的加载顺序

Go 1.11版本支持临时环境变量GO111MODULE,通过该环境变量来控制依赖包的管理方式。当GO111MODULE的值为on时,那么就会使用modules功能,这种模式下,$GOPATH不再作为build时导入的角色,依赖包会存放在$GOPATH/pkg/mod目录下。工程中的依赖包也会从此目录下查找。

当GO111MODULE的值为off时,不再使用modules功能。此时软件包的使用顺序为:

  • 优先使用vendor目录下面的包,

  • 如果vendor下面没有搜索到,再搜索$GOPATH/src下面的包,

  • 如果$GOPATH下面没有搜索到,那么搜索$GOROOT/src下面的包,

要么完整使用vendor下面的包,要么完整使用$GOPATH下面的包,不会混合使用。

当使用go mod vendor指令,将依赖包全部拷贝至当前项目下后,当前项目就可以随意拷贝分发,避免因网络问题造成接收者安装依赖包的麻烦。

有一个相关的工具包在这个地方:

github.com/marwan-at-work

有教程介绍它可以帮助我们管理依赖包,结束go.mod文件提供自动升级、降低版本的功能。

不要用它代替go mod,管理依赖直接使用go mod指令即可。这个依赖包安装后,在$GOPATH/bin目录下会有一mod二进制文件。执行mod与官方指令go mod并不是一回事。

这个工具包的主要作用有两点:

  • 可以快速在v1、v2或更高版本之间实现依赖的切换,用于快速演示,这确实比较酷

  • 如果代码老旧了,引用的是旧版本,与新版本不兼容导致无法编译,这时候可以通过长高或降纸版本号,让项目成功运行。

在项目的这个地方:

github.com/marwan-at-work/example

是一个举子。在example目录下执行mod upgrade或mod downgrade,可以将引用的example模块升级或降低版本号。执行指令后,查看subpkg/subpkg.go文件,可以看到import语句的变化。

这个工具不能代替go mod管理项目依赖,它仅能在特定场景下帮助开发者做一些事情。管理go语言的依赖包,还是推荐使用官方原生的go mod。

好了,我是石桥码农,今天的分享就在这里,有什么想法欢迎留言,也欢迎群内讨论。

2020年03月24日

d2d7359abbd82cc61dc642266f593037.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值