go的三种包管理方式

go语言的发展极其迅速,短短几年便已经历了高速变迁和进化,可能仅仅是几年前的项目,在现在的开发者眼中看起来都像是“上古时代”的产物。其中go的包管理方式就是其中一种,因为各种历史遗留原因导致目前go modulego pathgo vendor三种包管理方式在各种项目中都有混杂使用,这篇文章主要来介绍下三种方式的区别和优缺点,现在的go项目该选择哪一种。

先说结论,以目前的情况来说,更推荐选择go module


go pathgo vendor都是在发展的过程中因为不适应需求逐渐被更好的包管理方式替代,所以也不能说目前的go module就一定是最佳选择,只能说是目前的最佳实践。

两个命令
go install xxx(安装xxx第三方二进制可执行文件
go get xxx(下载xxx第三方依赖包并安装)
简单说go install类似go build, 将生成的可执行文件放到【$GOPATH/bin】目录中。go get是下载并安装,即git clone+go install,将clone的源码放到【$GOPATH/src】中。

需注意,go getgo 1.17开始官方不建议(deprecated)用于安装二进制可执行文件,并且从go 1.18开始不再支持。选项-d未来将成为默认参数,仅执行下载,不进行安装,这么做是为了更符合get的语义。所以安装二进制可执行文件推荐使用go install
参见Deprecation of 'go get' for installing executables

两个路径
GOROOT:go的安装目录,类似java的jdk,存放一些内置的开发包和工具。
GOPATH:go指定的工作空间,用于保存go项目的代码和第三方依赖包。

可以通过go env查看go相关的环境变量

三个包管理工具

  • go path【不推荐使用】

go path是最早的依赖包管理方式(Go1.0),启用GOPATH模式(注意区分GOPATH模式和GOPATH路径,这是两个语境),要求将所有工程代码要求放在GOPATH/src目录下。在工程经过go buildgo installgo get等指令后,会将拉取的第三方xxx依赖包放在GOPATH/src目录下,产生的二进制可执行文件放在GOPATH/bin 目录下,生成的中间缓存文件会被保存在 GOPATH/pkg下。
go path有什么问题呢?GOPATH模式下没有版本控制的概念,在执行 go get 的时候,获取的永远是最新的依赖包,下载到GOPATH/src,如果你有两个工程依赖一个包的v1和v2版本,则会发生冲突,因为 GOPATH 模式下两个工程内依赖的导入路径都是一样的,因此两个工程获取的都是v2版本。
所以这个模式已经不推荐使用了。

  • govendor【不推荐使用】

Go 1.5版本之后,Go 提供了 GO15VENDOREXPERIMENT 环境变量(Go 1.6版本默认开启该环境变量)和 Go vendor包管理工具,用于将 go build 时的应用路径搜索调整成为当前工程路径/vendor目录的方式,有效的解决了不同工程使用自己独立的依赖包问题。编译 Go 代码会优先从工程目录下的vendor目录先寻找依赖包,如果没有找到,然后GOPATH 中查找,都没找到最后在 GOROOT中查找。
优势:因为将第三方依赖完全和工程整合,完全本地化,使得项目构建速度快,且可以工作在无法连接外网的CI/CD流程中。
问题:放弃了依赖重用,使得冗余度上升。同一个依赖包如果不同工程想重用,都必须各自复制一份在自己的vendor目录下。

而且有趣的是,在go vendor库的官方README文件已经推荐改用go module了。

image.png

  • go module

Go1.11开始,官方推出Go module作为包管理工具,且从Go1.13开始为默认选择启用。GOMODULE模式下所有依赖的包存放在GOPATH/pkg/mod目录下,所有第三方二进制可执行文件放在GOPATH/bin目录下,且工程项目可以放在GOPATH路径之外,但要求项目中需要有go.mod文件(该文件通过go mod init命令初始化可以生成)。

GOMODULE模式和GOPATH模式一样都指定了依赖包存放的位置,而不是如vendor模式放入工程内,区别在于GOMODULE的go.mod文件中记录了所依赖包的具体版本,既实现了工程之间重用依赖包,且解决了GOPATH模式下不同工程无法依赖同一个包的不同版本的问题。

使用GO MODULE模式,需要先开启配置。在Go1.13之后,可以通过如下命令设置GO MODULE启用状态。

export GO111MODULE=on

GO111MODULE有三个可选值: onoffautogo 1.16之前默认autogo 1.16之后默认on

  • GO111MODULE=off 无模块支持,go 会从 GOPATH 和 vendor 文件夹寻找包。
  • GO111MODULE=on 模块支持,go 会忽略 GOPATH 和 vendor 文件夹,只根据 go.mod 下载依赖。
  • GO111MODULE=auto 在 $GOPATH/src 外面且根目录有 go.mod 文件时,开启模块支持。

关于GO111MODULE有兴趣的可以参考这篇文章 【Why is GO111MODULE everywhere, and everything about Go Modules (updated with Go 1.17)

go mod命令:go help mod查看相关帮助命令(govendor是第三方可执行文件,但是go mod命令是go自带的,不用额外go install)

命令 功能
go mod init 初始化当前文件夹,创建go.mod文件,事实上,如果你的环境中GO111MODULE=on,使用类似goland的工具创建工程会自动生成go.mod
go mod tidy 包整理(多的删去、少的拉取),使用之前自然是import了需要的库了
go mod download 下载依赖到本地(默认为 GOPATH/pkg/mod 目录)
go mod vendor 将依赖包复制到工程文件的vendor目录下

GO111MODULE=on且项目中包含go.mod文件时,执行go get xxx 或 go install xxx下载的或者二进制可执行文件将放入GOPATH/pkg/mod目录和GOPATH/bin目录下。


关于go.mod文件的具体内容解析,可以参考下面这篇文章:
深入Go Module之go.mod文件解析

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容