前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >go mod与 govendor 区别与使用

go mod与 govendor 区别与使用

作者头像
王小明_HIT
发布2021-07-05 16:32:13
1.3K0
发布2021-07-05 16:32:13
举报
文章被收录于专栏:程序员奇点程序员奇点

go mod 和 govendor 都是 Go 包管理器,类似 Java 工程的 maven

  • 2012年3月 Go 1 发布,此时没有版本的概念
  • 2013年 Golang 团队在 FAQ 中提议开发者保证相同 import path 的兼容性,后来成为一纸空文
  • 2013年10月 Godep
  • 2014年7月 glide
  • 2014年 有人提出 external packages 的概念,在项目的目录下增加一个 vendor 目录来存放外部的包
  • 2015年8月 Go 1.5 实验性质加入 vendor 机制
  • 2015年 有人提出了采用语义化版本的草案
  • 2016年2月 Go 1.6 vendor 机制 默认开启
  • 2016年5月 Go 团队的 Peter Bourgon 建立委员会,讨论依赖管理工具,也就是后面的 dep
  • 2016年8月 Go 1.7: vendor 目录永远启用
  • 2017年1月 Go 团队发布 Dep,作为准官方试验
  • 2018年8月 Go 1.11发布 Modules 作为官方试验
  • 2019年2月 Go 1.12发布 Modules 默认为 auto
  • 2019年9月 Go 1.13 版本默认开启 Go Mod 模式

有这么个故事

故事:失宠的 Vendor 目录

Vendor目录是Golang从1.5版本开始引入的,为项目开发提供了一种离线保存第三方依赖包的方法。但是到了Golang 1.11之后,由于引入了Module功能,在运行go build时,优先引用的是Module依赖包的逻辑,所以Vendor目录就被“无视”了,进而可能发生编译错误, moudle 说还是很想他,于是 提供了 go mod vendor 命令用来生成 vendor 目录。这样能避免一些编译问题,依赖可以先从 vendor 目录进行扫描。

代码语言:javascript
复制
$ go mod help vendor
usage: go mod vendor [-v]

Vendor resets the main module's vendor directory to include all packages needed to build and test all the main module's packages.
It does not include test code for vendored packages.

这句话的意思是:把 go mod init 后下载的相关依 赖包(Gopath 的 pkg) 目录,拷贝到 vendor 目录。

vendor 目录方式

go vendor 是go 1.5 官方引入管理包依赖的方式

基本思路: 将引用的外部包的源代码放在当前工程的vendor目录下面,go 1.6以后编译go代码会优先从vendor目录先寻找依赖包;找不到再从GOPATH 中寻找

解决的问题

将源码拷贝到当前目录下,这样导包当前工程代码到任意的机器的 ¥GOPATH/src 都可以编译通过,避免项目代码外部依赖过多

未解决的问题

无法精确的引用 外部包进行版本控制,不能指定引用某个特定版本的外部包,只是在开发时将其拷贝过来,但是一旦外部包升级,vendor 下面的包会跟着升级,而且 vendor 下面没有完整的引用包的版本信息, 对包升级带来了无法评估的风险。

什么是 GOROOT 和 GOPATH

  • GOROOT:golang的安装路径,当安装好go之后,默认会安装在/usr/local/go之下。GOROOT的主要作用是标识go的当前安装位置。
  • GOPATH:存放SDK以外的第三方类库;收藏的可复用的代码,包含三个子目录:-- src : 存放项目源码文件 -- pkg : 编译后的包文件 -- bin :编译后生成的可执行文件

要解决 vendor 目录 未解决的问题,使用 govendor

  • 可以平滑的将现有非 vendor 项目转换成 vendor 项目
代码语言:javascript
复制
govendor add  inport_out_packagename
  • 会生成一个元数据文件,记录工程依赖的外部包,及其版本信息
代码语言:javascript
复制
vendor.json
  • 提高命令查看整个工程的依赖关系
代码语言:javascript
复制
goverdor --list 
goverdor --list -v

govendor

govendor 是一个基于 vendor 机制实现的 Go 包依赖管理命令行工具。与原生 vendor 无侵入性融合,也支持从其他依赖管理工具迁移,可以很方便的实现同一个包在不同项目中不同版本、以及无相互侵入的开发和管理。

在执行 go build 或 go run 命令时,会按照以下顺序去查找包:

  • 当前包下的 vendor 目录
  • 向上级目录查找,直到找到 src 下的 vendor 目录
  • 在 GOROOT 目录下查找
  • 在 GOPATH 下面查找依赖包

常用命令

状态参数

  1. 安装
代码语言:javascript
复制
go get -u -v github.com/kardianos/govendor
  1. 初始化
代码语言:javascript
复制
cd xxx
govendor init

初始化完成后,项目目录中会生成一个vendor文件夹,包含一个vendor.json文件,json文件中包含了项目所依赖的所有包信息

代码语言:javascript
复制
{
 "comment": "",
 "ignore": "test",
 "package": [],
 "rootPath": "govendor-example"
}
将已被引用且在 $GOPATH 下的所有包复制到 vendor 目录
代码语言:javascript
复制
govendor add +external
仅从 $GOPATH 中复制指定包
代码语言:javascript
复制
govendor add gopkg.in/yaml.v2
列出代码中所有被引用到的包及其状态
代码语言:javascript
复制
govendor list

运行结果

代码语言:javascript
复制
e  github.com/gin-contrib/sse
 e  github.com/gin-gonic/gin
 e  github.com/gin-gonic/gin/binding
 e  github.com/gin-gonic/gin/internal/json
 e  github.com/gin-gonic/gin/render
 e  github.com/golang/protobuf/proto
 e  github.com/mattn/go-isatty
 e  github.com/ugorji/go/codec
 e  gopkg.in/go-playground/validator.v8
 e  gopkg.in/yaml.v2
pl  govendor-example
  m github.com/json-iterator/go
  m golang.org/x/sys/unix
列出一个包被哪些包引用
代码语言:javascript
复制
govendor list -v fmt
代码语言:javascript
复制
 s  fmt
    ├──  e  github.com/gin-contrib/sse
    ├──  e  github.com/gin-gonic/gin
    ├──  e  github.com/gin-gonic/gin/render
    ├──  e  github.com/golang/protobuf/proto
    ├──  e  github.com/ugorji/go/codec
    ├──  e  gopkg.in/go-playground/validator.v8
    ├──  e  gopkg.in/yaml.v2
    └── pl  govendor-example

使用建议

  • 使用govendor管理项目并进行项目协作时,我们每次不需要提交整个vendor目录,而只需要提交json文件,十分方便。一个配置文件全部搞定!
  • vendor 目录解决了工程依赖打包的问题,可将依赖与工程一起打包,减少下载依赖的时间。
  • 同一个项目只创建一个govendor目录,且在代码库的一级目录。

缺点

  • 依赖包全部都在vendor目录下,每个项目都有一份,所以每次拉取项目时都会拉一遍依赖。
  • govendor不区分包版本,意味着开发期间拉的依赖的包很可能跟上线后的拉的依赖包版本不一致,很危险。
  • govendor add +e会拉取全部外部包,即使是本项目没有用到的,这样会造成大量的冗余。但是只用govendor add +指定包又很麻烦。

go mod

go module是Go1.11版本之后官方推出的版本管理工具,并且从Go1.13版本开始,go module将是Go语言默认的依赖管理工具。

包不再保存在GOPATH中,而是被下载到了$GOPATH/pkg/mod路径下.

go mod vendor 会将依赖包放到 vendor 目录

在这里插入图片描述

  • go.mod文件记录了项目所有的依赖信息,其结构大致如下:
代码语言:javascript
复制
module github.com/Q1mi/studygo/blogger

go 1.12

require (
 github.com/DeanThompson/ginpprof v0.0.0-20190408063150-3be636683586
 github.com/gin-gonic/gin v1.4.0
 github.com/go-sql-driver/mysql v1.4.1
 github.com/jmoiron/sqlx v1.2.0
 github.com/satori/go.uuid v1.2.0
 google.golang.org/appengine v1.6.1 // indirect
)
  • go.sum是一个构建状态跟踪文件。它会记录当前module所有的顶层和间接依赖,以及这些依赖的校验和,来确保这些模块的将来下载内容与第一次下载的内容相同,但是第一次下载的模块也有可能是非法的(代理服务不可信、模块源被黑等),所以Go 1.13推出GOSUMDB(Go CheckSum Database)用来公证模块的Hash值,从而提供一个可以100%复现的构建过程并对构建对象提供安全性的保证,同时还会保留过去使用的包的版本信息,以便日后可能的版本回退。

go mod

在这里插入图片描述

go mod 与 go vendor 区别

在这里插入图片描述

微信号:程序员开发者社区

博客:CSDN 王小明

关注我们,了解更多

参考资料

  • https://studygolang.com/articles/8298
  • https://zhuanlan.zhihu.com/p/59191567
  • https://shockerli.net/post/go-package-manage-tool-govendor/
  • https://www.liwenzhou.com/posts/Go/go_dependency/
  • https://wangxiaoming.blog.csdn.net/article/details/113665107
  • https://segmentfault.com/a/1190000019724582
  • https://www.cnblogs.com/youhui/articles/11152843.html
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-05-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员奇点 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • vendor 目录方式
    • 解决的问题
      • 未解决的问题
        • 什么是 GOROOT 和 GOPATH
          • 要解决 vendor 目录 未解决的问题,使用 govendor
          • govendor
            • 常用命令
              • 将已被引用且在 $GOPATH 下的所有包复制到 vendor 目录
              • 仅从 $GOPATH 中复制指定包
              • 列出代码中所有被引用到的包及其状态
              • 列出一个包被哪些包引用
            • 使用建议
              • 缺点
              • go mod
                • go mod
                  • go mod 与 go vendor 区别
                    • 参考资料
                    相关产品与服务
                    命令行工具
                    腾讯云命令行工具 TCCLI 是管理腾讯云资源的统一工具。使用腾讯云命令行工具,您可以快速调用腾讯云 API 来管理您的腾讯云资源。此外,您还可以基于腾讯云的命令行工具来做自动化和脚本处理,以更多样的方式进行组合和重用。
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档