Go Modules 日常使用

1. 初始化

新项目,我们可以使用 go mod init 初始化生成 go.mod 文件

go mod init

2. Go Proxy

因国内访问外网受限,一般我们都会配合 Go Proxy 使用,以防止使用 go get 获取源码包时花费时间过长或无法下载

go env -w  GOPROXY=https://goproxy.cn

知识点: 我们使用 go env -w 来修改 Go 相关的环境变量。

Go Proxy 设置完成后即可放心使用 go get 来下载依赖了,作为测试,我们下载 HttpRouter :

go get github.com/julienschmidt/httprouter

使用 Proxy 的情况下一般很快就能下载完成。

安装 package 的原则是先拉最新的 release tag,若无 tag 则拉最新的 commit。

3. go.mod

每一次的 go get 都会同时修改 go.modgo.sum 文件。

这两个文件是下载依赖包的主要依据。go.mod 类似于 PHP 中的 composer.json ,而 go.sum 则是 composer.lock

打开查看 go.mod 的源码:

go.mod

module demo

go 1.15

require (
    github.com/gorilla/mux v1.7.4
    github.com/julienschmidt/httprouter v1.3.0 // indirect
)

几个参数:

  • module —— 我们的 goblog 在 Go Module 里也算是一个 Module ;
  • go —— 指定了版本要求,最低 1.15
  • require —— 是项目所需依赖

4. go.sum

go.sum 文件保存着依赖包的版本和哈希值:

go.sum

github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=

需要注意的是,go.sum 里不止会保存直接依赖包的哈希值,间接依赖包的哈希值也会被保存。

什么是间接依赖包?

间接依赖包就是依赖包的依赖,以及他们的依赖… 我们目前下载的两个包 mux 和 httprouter,没有间接依赖,接下来我们拉取知名的 gin 框架来试试:

go get github.com/gin-gonic/gin

下载成功后打开 go.sum ,会发现里面的内容远远多于 go.mod。这是因为 gin 有很多依赖包,而这些依赖包也会有自己的依赖。

接下来我们仔细看下,每个模块路径有如下两种哈希:

github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=

前者为 Go Modules 打包整个模块包文件 zip 后再进行 hash 值,而后者为针对 go.mod 的 hash 值。

由此可见,go.sum 是保证所下载源码 100% 正确的重要依据。如果有恶意用户,将某个 Git 项目的 tag 源码做了修改,这些哈希值将会不匹配并报错。

因为 go.sum 有 100% 保证 build 一致的作用,我们建议开发中将其加入到代码版本控制器中。这里面不止有安全的因素,当同事或者其他人 clone 你的代码,我们也希望代码可以保持一致。

5. indirect

回到我们的 go.mod 中,可以看到 require 区块里有 // indirect 字样:

module blog

go 1.15

require (
	github.com/gin-gonic/gin v1.7.2 // indirect
	github.com/gorilla/mux v1.8.0
)

此标志标明这个依赖包还未被使用,如果你在代码的某个地方 import 到的话,VSCode以及PHPSTORM 的 Go 插件就会自动将这个标志去除。

6. go mod tidy 命令

此命令做整理依赖使用,执行时会把未使用的 module 移除掉,我们试试:

go mod tidy

再次查看 go.modgo.sum 文件,会发现我们上面测试引入的两个包,因未使用,皆被移除。

7. 源码包的存放位置

默认源码包存放于 $GOPATH/pkg/mod 中,你可以打开看下。我的如下

8. 清空 Go Modules 缓存

使用以下命令可以清空本地下载的 Go Modules 缓存:

go clean -modcache

9. 下载依赖

默认情况下,当 go rungo build 命令执行时,Go 会基于自动go.mod 文件自动拉取依赖。

Go Module 也提供了一个命令用以下载项目所需依赖:

go mod download

10. 所有 Go Modules 命令

以下是完整的命令列表

命令作用
go mod init生成 go.mod 文件
go mod download下载 go.mod 文件中指明的所有依赖
go mod tidy整理现有的依赖
go mod graph查看现有的依赖结构
go mod edit编辑 go.mod 文件
go mod vendor导出项目所有的依赖到 vendor 目录
go mod verify校验一个模块是否被篡改过
go mod why查看为什么需要依赖某模块

11. 相关环境变量

1). GO111MODULE

此变量为 Go modules 的开关,此值有以下几个可能:

  • auto:项目包含了 go.mod 文件的话启用 Go modules,目前在 Go1.11 至 Go1.15 中仍然是默认值。
  • on:启用 Go modules,推荐设置,将会是未来版本中的默认值。
  • off:禁用 Go modules,不推荐设置。

因是在 Go1.11 版本添加,故命名为 GO111MODULE

未来 GO111MODULE 会先调整为默认值为 on(曾经在 Go1.13 想改为 on,并且已经合并了 PR,但最后因为种种原因改回了 auto),然后再把 GO111MODULE 这个变量去掉,目前猜测会在 Go 2。太早去掉 GO111MODULE 的支持,会存在兼容性问题

2). GOPROXY

此变量用于设置 Go 模块代理(Go module proxy),其作用是拉取源码时能够脱离传统的 VCS 方式,直接通过镜像站点来快速拉取。

镜像的好处多多,一个是防止某个版本的代码被有意或无意删除。第二是能将源码压为 zip 包,方便传输。最重要的 —— 可以做镜像加速站点,这在例如国内这种不稳定的网络环境下尤为重要。

GOPROXY 的默认值是

https://proxy.golang.org,direct

然而 proxy.golang.org 在国内是无法访问的,所以我们使用 Go modules 时,需设置国内的 Go 模块代理:

go env -w GOPROXY=https://goproxy.cn,direct

信息goproxy.cn 是一个由 CDN 提供商七牛云支持的非营利性项目。七牛云也是中国最早在生产环境中使用 Go 的公司之一,项目介绍请见https://github.com/goproxy/goproxy.cn/blob/master/README.zh-CN.md

GOPROXY 的值是一个以英文逗号 , 分割的 Go 模块代理列表,可设置多个模块代理。将其设置为 off ,将会禁止 Go 在后续操作中使用任何 Go 模块代理。

direct 标志

direct 标志意味着从源地址抓取(比如 GitHub 等)。

如我们设置 GOPROXY 的值为:

https://goproxy.cn,direct

则告诉 go get 在获取源码包时先尝试 https://goproxy.cn,如果遇到 404 等错误时,再尝试从源地址抓取。

3). GOSUMDB

此值是 Go Checksum Database 的缩写,用于在拉取模块版本时(无论是从源站拉取还是通过 Go Module Proxy 拉取)保证拉取到的模块代码包未经过篡改,若发现不一致将会立即中止。

GOSUMDB 的默认值为:

sum.golang.org

在国内同样无法访问,所幸 GOSUMDB 可以被 Go Module Proxy 代理。我们所设置的模块代理 goproxy.cn 支持代理 sum.golang.org

另外,此变量还可设置为 off,会禁止 Go 在后续操作中校验模块哈希。

4). GONOPROXY/GONOSUMDB/GOPRIVATE

这三个环境变量都是用在依赖了私有模块,这些模块 GOPROXY 和 GOSUMDB 都无法读取。

  • GONOPROXY —— 设置不走 Go Proxy 的 URL 规则;
  • GONOSUMDB —— 设置不检查哈希的 URL 规则;
  • GOPRIVATE —— 设置私有模块的 URL 规则,会同时设置以上两个变量。

因为 GOPRIVATE 会同时设定以上两个,所以一般私有仓库使用 GOPRIVATE 即可。

以上三个值,都可使用逗号分隔来设置多个选项。例如:

go env -w GOPRIVATE="git.example.com,github.com/name/project"

设置后当 go get 时,前缀为 git.example.comgithub.com/name/project 的模块都会被认为是私有模块。

我们也可以利用通配符,例如:

go env -w GOPRIVATE="*.example.com"

这样子设置的话,所有模块路径为 example.com 的子域名(例如:git.example.com)都将不经过 Go module proxyGo checksum database,需要注意的是不包括 example.com 本身。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值