概述
文章目录
- 1. 开启Go module
- 1.11和1.12版本
- 1.13版本之后
- goLand开启 go mod
- 2. go get使用
- 3. mod基本操作
- 4. mod高级操作
- 4.1 retract
- 5. 进阶
- 5.1 版本号规范
- 5.2 伪版本
- 5.3 indirect标志
- 5.3.1 直接依赖未启用 Go module
- 5.3.2 直接依赖go.mod 文件中缺失部分依赖
- 5.3.3 如果查找间接依赖
- 5.4 replace使用
- 5.5 exclude使用
- 5.6 包缓存
- 5.7 下载过程查看
- 6. 下载路径替换
环境
- Windows10
- GO:1.13
1. 开启Go module
1.11和1.12版本
将下面两个设置添加到系统的环境变量中
GO111MODULE=on
GOPROXY=https://goproxy.io
1.13版本之后
需要注意的是这种方式并不会覆盖之前的配置,有点坑,你需要先把之前的给删掉再设置
# 1.13之后,这个都是默认开启的
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,https://goproxy.io,direct
如果遇到校验go.sum出现问题的,把GOSUMDB
关掉就好了
go env -w GOSUMDB=off
或者将域名设置为私有
go env -w GOPRIVATE=pibigstar.com
goLand开启 go mod
2. go get使用
使用go module之后,go get 拉取依赖的方式就发生了变化
- 下载项目依赖
go get ./...
- 拉取最新的版本(优先择取 tag)
go get golang.org/x/text@latest
- 拉取 master 分支的最新 commit
go get golang.org/x/text@master
- 拉取 tag 为 v0.3.2 的 commit
go get golang.org/x/text@v0.3.2
- 拉取 hash 为 342b231 的 commit,最终会被转换为 v0.3.2:
go get golang.org/x/text@342b2e
- 指定版本拉取,拉取v3版本
go get github.com/smartwalle/alipay/v3
- 更新
go get -u
查看可执行文件的mod信息
go version -m gen
3. mod基本操作
- 初始化一个moudle,模块名为你项目名
go mod init 模块名
- 下载modules到本地cache
目前所有模块版本数据均缓存在
$GOPATH/pkg/mod
和 $GOPATH/pkg/sum
下
go mod download
- 编辑go.mod文件
选项有-json
、-require
和-exclude
,可以使用帮助go help mod edit
go mod edit
- 以文本模式打印模块需求图
go mod graph
- 删除错误或者不使用的modules
go mod tidy
- 生成vendor目录
go mod vendor
- 验证依赖是否正确
go mod verify
- 查看依赖关系
go mod why -m githuh.com/pibigstar/go-demo
4. mod高级操作
- 更新到最新版本
go get github.com/gogf/gf@version
如果没有指明 version 的情况下,则默认先下载打了 tag 的 release 版本,比如 v0.4.5 或者 v1.2.3;如果没有 release 版本,则下载最新的 pre release 版本,比如 v0.0.1-pre1。如果还没有则下载最新的 commit
- 更新到某个分支最新的代码
go get github.com/gogf/gf@master
- 更新到最新的修订版(只改bug的版本)
go get -u=patch github.com/gogf/gf
- 替代只能翻墙下载的库
go mod edit -replace=golang.org/x/crypto@v0.0.0=github.com/golang/crypto@latest
go mod edit -replace=golang.org/x/sys@v0.0.0=github.com/golang/sys@latest
- 清理moudle 缓存
go clean -modcache
- 查看可下载版本
go list -m -versions github.com/gogf/gf
- 查看撤回的版本(1.16后才支持)
go list -m -versions -retracted github.com/polaris1119/foo
- 查看当前项目中是否依赖了撤回的版本
go list -m -u all
4.1 retract
它可以帮助我们撤回某个版本,比如你推送了 v0.2.0 版本,这时别人都依赖了你的 v0.2.0 版本,但你突然发现这个版本有bug,但你不能删除这个版本了,这时你可以发布一个 v0.2.1版本,该版本的go.mod里面增加 retract v0.2.0 将 v0.2.0 版本给撤回,这时别人如果依赖了v0.2.0版本就会给别人提醒,类似于 函数注释 Deprecate 功能
module github.com/pibigstar/go-demo
go 1.16
retract (
// 这个版本有bug
v0.2.0
// 也可撤回多个版本
[v1.0.0, v1.0.1]
)
5. 进阶
5.1 版本号规范
go mod 对版本号的定义是有一定要求的,它要求的格式为
v<major>.<minor>.<patch>
,如果major版本号大于1时,其版本号还需要体现在Module名字中。比如 我的项目github.com/pibigstar/go-demo
,如果我的版本号增长到v2.x.x
时,我的Module名字也需要相应的改变为:github.com/pibigstar/go-demo/v2
, 有人可能就要问了,我不改可以吗? 可以的!但是go mod 会在你依赖的后面打一个+incompatible
标志
5.2 伪版本
我们将项目上传到github后,如果不打tag,或tag不符合
v<major>.<minor>.<patch>
这个格式,那么当我们用go mod 去拉这个项目的时候,就会将commitId
作为版本号,它的格式大概是vx.y.z-yyyymmddhhmmss-abcdef格式
虽然不太好看,但是这个玩意其实挺有用的,省的你每次都需要打tag了,这里介绍一个如果直接拉取最后一次提交的版本
require (
github.com/pibigstar/go-demo master
)
我们直接在后面写 master
分支,这样它就会拉取master分支最后一次提交的commitId
作为版本号
5.3 indirect标志
我们用 go mod 的时候应该经常会看到 有的依赖后面会打了一个
// indirect
的标识位,这个标识位是表示 间接的依赖。
什么叫间接依赖呢?打个比方,项目A依赖了项目B,项目B又依赖了项目C,那么对项目A而言,项目C就是间接依赖,这里要注意,并不是所有的间接依赖都会出现在 go.mod文件中。间接依赖出现在go.mod文件的情况,可能符合下面的场景的一种或多种:
- 直接依赖未启用 Go module
- 直接依赖go.mod 文件中缺失部分依赖
5.3.1 直接依赖未启用 Go module
如下图所示,Module A 依赖 B,但是 B 还未切换成 Module,即没有go.mod文件,此时,当使用go mod tidy命令更新A的go.mod文件时,B的两个依赖B1和B2将会被添加到A的go.mod文件中(前提是A之前没有依赖B1和B2),并且B1 和B2还会被添加// indirect
的注释。
那么项目A的依赖关系就会变成下面这个样子
require (
B vx.x.x
B1 vx.x.x // indirect
B2 vx.x.x // indirect
)
5.3.2 直接依赖go.mod 文件中缺失部分依赖
如下图所示,Module B虽然提供了go.mod文件中,但go.mod文件中只添加了依赖B1,那么此时A在引用B时,则会在A的go.mod文件中添加B2作为间接依赖,B1则不会出现在A的go.mod文件中。
此时项目A的依赖关系就会变成下面这个样子
require (
B vx.x.x
B2 vx.x.x // indirect
)
间接依赖出现在go.mod中,可以一定程度上说明依赖有瑕疵,要么是其不支持Go module,要么是其go.mod文件不完整。
由于Go 语言从v1.11版本才推出module的特性,众多开源软件迁移到go module还需要一段时间,在过渡期必然会出现间接依赖,但随着时间的推进,在go.mod中出现// indirect的机率会越来越低。
出现间接依赖可能意味着你在使用过时的软件,如果有精力的话还是推荐尽快消除间接依赖。可以通过使用依赖的新版本或者替换依赖的方式消除间接依赖。
5.3.3 如果查找间接依赖
可以通过 go mod why -m <pkg>
来查看这个间接依赖是被谁引入的
5.4 replace使用
replace指替换,它指示编译工具替换require指定中出现的包
这里要注意两点:
- replace只在 main module里面有效
什么叫main module? 打个比方,项目A 的module用replace替换了本地文件,那么当项目B引用项目A后,项目A的replace会失效,此时对replace而言,项目A就是 main module
- replace指定中需要替换的包及其版本号必须出现在require列表中才有效
这里我再简单谈下replace的使用场景
- 替换无法下载的包
- 替换本地自己的包
- 替换fork包
有时候我们依赖的第三方库可能有bug,我们就可以fork一份他们的库,然后自己改下,然后通过replace将我们fork的替换成原来的
5.5 exclude使用
go.mod文件中的exclude指令用于排除某个包的特定版本,其与replace类似,也仅在当前module为main module时有效,其他项目引用当前项目时,exclude指令会被忽略。
exclude指令在实际的项目中很少被使用,因为很少会显式地排除某个包的某个版本,除非我们知道某个版本有严重bug。 比如指令exclude github.com/pibigstar/go-demo v1.1.0
,表示不使用v1.1.0 版本。
5.6 包缓存
最后简单谈一下当我们使用 go mod 后包缓存存储问题,依赖包存储在
$GOPATH/pkg/mod
,该目录中可以存储特定依赖包的多个版本。需要注意的是$GOPATH/pkg/mod
目录下有个cache
目录,它用来存储依赖包的缓存,简单说,go命令每次下载新的依赖包都会在该cache目录中保存一份,每个版本都会有一份缓存。
值得注意的是包名大小写问题,有时我们使用的包名中会包含大写字母,GOMODULE
模式下,在存储时会将包名做大小写编码处理,即每个大写字母将变!+相应的小写字母
,比如github.com/pibigstar/GO-demo
包在存储时将会被放置在$GOPATH/pkg/mod/github.com/pibigstar/!g!o-demo
目录中。所以这里我不推荐你用大写字母定义包名
5.7 下载过程查看
我们可以在包下载路径后面新增
?go-get=1
参数,然后浏览器访问 https://gitee.com/pibigstar/go-demo?go-get=1,然后查看源码就能看到该包拉取的具体路径是什么
6. 下载路径替换
当我们的module不是放在域名的443或80端口时,这时就会比较麻烦,因为go mod 不支持 pibigstar.com:8000/group/util
这种结构,这种是无法下载的,不过我们可以使用 git 的替换功能,实现这个下载
git config --global url."http://pibigstar.com:8000/".insteadof "https://pibigstar.com/"
这样我们使用go mod 就可以用下面的路径
require (
pibigstar.com/group/util v1.0.0
)
这个pibigstar.com
是可以随意写的,只要是一个可访问的域名
最后
以上就是温暖八宝粥为你收集整理的go mod 常用操作1. 开启Go module2. go get使用3. mod基本操作4. mod高级操作5. 进阶6. 下载路径替换的全部内容,希望文章能够帮你解决go mod 常用操作1. 开启Go module2. go get使用3. mod基本操作4. mod高级操作5. 进阶6. 下载路径替换所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复