Go Module | 青训营

写在前面

关于 Go Module 的详细资料,可以参考官方的文档。

Go Modules Reference

文章详细地介绍了Go Module的设计以及原理,包含各种命令的使用和 Go 版本的兼容情况。

Go 包管理历史

Go 的包管理大致可以分为3个阶段:GOPATH、vendor、Go Module。

  1. GOPATH

GOPATH 是 Go 的一个环境变量,程序所依赖的包都放在 GOPATH 下面。一般来讲,GOPATH 默认是用户目录/go,Linux 下是/home/username/go,Windows 下是C:\Users\username\go。目录下要有三个文件夹:

  • bin:项目编译的二进制文件
  • pkg:项目编译的中间产物,加速编译
  • src:项目源码

在工程经过go buildgo installgo get等指令后,会将下载的第三方包源代码文件放在$GOPATH/src目录下, 产生的二进制可执行文件放在 $GOPATH/bin目录下,生成的中间缓存文件会被保存在 $GOPATH/pkg 下。

这种包管理方式在多个项目依赖不同版本的包时存在显而易见的冲突问题,所以出现了 vendor。

  1. vendor

vendor 意为供应商,在项目目录下新增一个 vendor 文件夹,项目在查找依赖时,将会优先从 vendor 文件夹下查找依赖。使用 go mod vendor命令将会创建当前依赖的副本并存储到$ProjectPath/vendor下。

  1. Go Module

Go Module 是 Go 11开始支持的包管理方式,如果没有兼容性的考虑,请使用 Go Module 创建项目,而不再使用 Go Path。在 Go Module 的工程下,会存在一个go.mod文件,这是一个模块的描述文件,声明了当前项目是一个 Go Module,并且声明了名字、版本、依赖等信息。同时还会存在一个go.sum文件,这是一个用来保存依赖校验和的文件,防止依赖被篡改。

当开启模块支持时,第 1 部分说的 GOPATH 的意义会发生一点变化。

In module-aware mode, GOPATH no longer defines the meaning of imports during a build, but it still stores downloaded dependencies (in GOPATH/pkg/mod; see Module cache) and installed commands (in GOPATH/bin, unless GOBIN is set).

也就是说 GOPATH/pkg/mod 会被当做存放下载的依赖的仓库,称为 Module Cache。如果想要清除 Cache,可以使用go clean -modcache删除该目录下的所有已下载的依赖。

模块的使用

如何知道当前 Go 采用怎么样的包管理行为呢?我们可以使用go env命令查看当前的环境变量设置,其中GO11MODULE变量的值决定了Go的包管理行为。

  • If GO111MODULE=off, the go command ignores go.mod files and runs in GOPATH mode.
  • If GO111MODULE=on or is unset, the go command runs in module-aware mode, even when no go.mod file is present. Not all commands work without a go.mod file: see Module commands outside a module.
  • If GO111MODULE=auto, the go command runs in module-aware mode if a go.mod file is present in the current directory or any parent directory. In Go 1.15 and lower, this was the default behavior. go mod subcommands and go install with a version query run in module-aware mode even if no go.mod file is present.

简单来说就是,如果关闭模块支持则继续沿用GOPATH的规则;如果开启模块支持,则一律采用Go Module的支持;如果设置为自动,则取决于当前项目根路径下是否存在go.mod文件。

开启 vendor时,go buildgo test等命令将只考虑vendor目录下的包,而不再从网络或者module cache下找包。

但是go getgo mod downloadgo mod tidy等不受影响,还是会下载包到module cache

常用命令

  1. go mod init: 用来初始化模块
  2. go mod tidy: 添加依赖并移除不需要的依赖项
  3. go get: 获取依赖,如果不存在将从网络下载,同时更新go.mod的依赖项

使用go get package@version,可以获取指定版本的包。
除了具体的版本,也可以是@master、@latest、@git-tag。
特别的是,使用@none可以移除包依赖。

# Remove a dependency on a module and downgrade modules that require it
# to versions that don't require it.
$ go get golang.org/x/text@none

go get 与 go install

  1. go get会下载依赖,同时更新go.mod文件
  2. go install则是下载、编译、安装依赖(如果存在ExecuablesProgramsCommands也就是main package,则会安装到GOBIN下,否则只是下载到module cache),不会修改go.mod文件。

原本go get也会编译安装,如果加入-d参数,则不会进行编译安装。

-d参数在 Go 1.17已经过时,自从 Go 1.18 后,总是默认启用。

官方建议使用go get进行依赖的管理,而使用go install进行可执行文件的安装。

参考资料

[1] Go Modules Reference

[2] 拜拜了,GOPATH君!新版本Golang的包管理入门教程 – 掘金 (juejin.cn)

[3] go mod 使用 – 掘金 (juejin.cn)

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYQA4jte' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片