Jochen的goland小抄-番外篇-go mod
mod是go推出的包管理工具,为了解决项目依赖文件的问题,一个module是go相关包版本信息的收集单元。记录了精准的必须依赖信息和重新编译依赖。本小抄参考的是我是码客的博客,写的实在是通俗易懂,深得我心,此外还有这篇说的也不错
go modules
一个模块是分发包的集合。可以直接从版本控制存储库或模块代理服务器下载模块。
使用go mod
目前go项目不需要去依赖gopath去编写源代码了,使用gomod可以更好的管理我们项目的依赖关系
- 设定GO111MODULE环境变数:
该参数是为了设置是否开启MODULES功能,有三个值可选
-
auto:
默认值,go命令会根据当前目录来决定是否启用modules功能。需要满足两种情形:
- 该专案目录不在GOPATH/src/下
- 当前或上一层目录存在go.mod档案
-
on: go命令会使用modules,而不会GOPATH目录下查找。
-
off: go命令将不会支持module功能,寻找套件如以前GOPATH的做法去寻找。
-
初始化mod
go mod init <module name>
,module name
module name可以是任意的命名,但是一定要指定,否则会报错 go: cannot determine module path for source directory。 -
初始化mod后在当前项目文件会生产go.mod文件,里面存放的是工程包的依赖信息
~/workspace/GoWork >>> cat go.mod module mytest go 1.15 require github.com/sirupsen/logrus v1.7.0
如果不指定依赖包的版本信息,go build默认会替我们去拉去该依赖包的最新版本
go.mod文件中可以写以下几个关键字:
- module :module名,可用于导包
- go:定义go语言版本
- require:指定依赖的包,默认为最新版本,可以指定版本号
- exclude:排除该依赖包和其版本
- replace:使用不同的依赖包并替换原有的依赖包本
- indirect:代表被间接导入的依赖包
-
go build或者go download后,项目目录下会去搜寻或下载依赖(如果依赖的包在goroot/gopath就直接拿来用,否则会下载到GOPATH/pkg/mod中,因为GOPATH存储的是第三方库)生成一个可执行文件和go.sum,go.sum里面存放的是依赖包的校验信息,即依赖包版本的关系,确保是正确的,不怎么需要鸟它(我们主要关注的还是上面的mod)
~/workspace/GoWork >>> cat go.sum
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-
还可以使用go get
方式直接下载依赖包而不用在go.mod中定义 只要有开启
go modules
功能,go get
就不会像以前一样在GOPATH/src
下放置套件档案,而是会放在GOPATH/pkg/mod
里面,并且go.mod
会写好引入,这样也就不用使用go mod download
指令了。
编辑gomod
$ go mod
Go mod provides access to operations on modules.
Note that support for modules is built into all the go commands,
not just 'go mod'. For example, day-to-day adding, removing, upgrading,
and downgrading of dependencies should be done using 'go get'.
See 'go help modules' for an overview of module functionality.
Usage:
go mod <command> [arguments]
The commands are:
download download modules to local cache
edit edit go.mod from tools or scripts
graph print module requirement graph
init initialize new module in current directory
tidy add missing and remove unused modules
vendor make vendored copy of dependencies
verify verify dependencies have expected content
why explain why packages or modules are needed
Use "go help mod <command>" for more information about a command.
-
download :下载依赖包到缓存目录
-
edit:编辑go.mod
- -fmt 格式化go.mod文件
- -require=$package:@version添加依赖,会覆盖已存在的相同依赖。添加依赖更推荐使用go get,因为go get会更新相关的go.mod文件,而edit只会更新你指定的go.mod文件。
- -droprequire=$package:@version 移除依赖
- -replace=$oldPackage=$newPackage 更新已经存在的依赖。通常用于私有仓库代码覆盖共有仓库。
-
graph:显示依赖关系(图)
~/workspace/GoWork >>> go mod graph mytest github.com/sirupsen/logrus@v1.7.0 github.com/sirupsen/logrus@v1.7.0 github.com/davecgh/go-spew@v1.1.1 github.com/sirupsen/logrus@v1.7.0 github.com/pmezard/go-difflib@v1.0.0 github.com/sirupsen/logrus@v1.7.0 github.com/stretchr/testify@v1.2.2 github.com/sirupsen/logrus@v1.7.0 golang.org/x/sys@v0.0.0-20191026070338-33540a1f6037 ~/workspace/GoWork >>>
-
tidy:增加缺失的包并且移除没有依赖的包。自动去下载依赖包,并且缓存到$GOPATH/pkg/mod目录下。
ps:需要注意的是,tidy会自动更新依赖包的版本,所以如果不是初建的项目还是尽量少用tidy,尽量用go get精准控制新增的依赖包。 -
vendor:把所有依赖包拷贝到vendor目录底下(而不是缓存在$GOPATH/pkg/mod)下,这简直是环境迁移的利器
-
verify:校验依赖关系
-
why:指出某一个特定包的依赖关系(graph是指出所有)
注意:在一个项目中,我们mod init
如果GOPATH没有指定,又没有指定module的名字则报错:
最后附上一篇vscode配置基于gomod的go开发环境:https://developer.51cto.com/art/202009/625807.htm?pc