提出问题
如今版本(1.18)的Go语言,配置环境时,是否需要像go mod出现之前一样设置$GOPATH或vendor?go mod的包依赖管理机制是否可以替代掉$GOPATH来进行项目开发?
问题起源
上周在实验室编写Web,在Go中使用数据库,用到了Github.com里的go-sql-driver驱动。学长在演示导入包的时候,建议我可以不用把导入的package全部放在$GOPATH/src的文件夹中,通过go mod tidy
即可自动添加本地不存在的包,并可以删除掉未使用的包。
问题发展
就在学长试图在我的项目中使用go mod时,由于我的GO111MODULE=auto
,导致go mod 命令在 $GOPATH 里无法执行,因为 GO111MODULE 的默认值 auto
,在该设置下,默认在$GOPATH 里不会执行, 如果一定要强制执行,要么设置环境变量为 on
:
可以使用如下命令更改go env
:
go env -w GO111MODULE=on
要么使用go mod init
自动新建一个go.mod文件(但是在Goland中,后来新建了go.mod仍然可能导致import标红,提示找不到包,也无法在依赖库中找到GO MODULE)。
在使用模块的时候, $GOPATH 是无意义的,不过它还是会把下载的依赖储存在 $GOPATH/src/mod 中,也会把go install
的结果放在 $GOPATH/bin(如果 $GOBIN 不存在的话)
问题解决
go mod作为go语言官方最新发布的包管理工具,自然是存在优越性的。
在经过我与学长不断尝试的过程中,我更进一步地体验到了go mod带给我项目包管理的便利。它让程序员可以自由地在电脑上任一文件夹进行go程序的编写,而不再受制于GOPATH,导致项目文件和包文件混杂在一起。
使用go mod管理包,完全可以不再使用$GOPATH,在项目中仅需简单的 go mod tidy
,即可完美地做好管理。
注意事项
go mod init
在没有接module名字的时候是执行不了的,会报错 go: cannot determine module path for source directory
。可以这样执行:
go mod init [一个可以和go文件名不相同的名字]
常用的go mod命令汇总
go mod download
下载模块到本地缓存,缓存路径是 $GOPATH/pkg/mod/cache
go mod edit
是提供了命令版编辑 go.mod 的功能,例如如下命令会格式化 go.mod
go mod edit -fmt go.mod
go mod graph
把模块之间的依赖图显示出来
go mod init
初始化模块(例如把原本dep管理的依赖关系转换过来)
go mod tidy
增加缺失的包,移除没用的包
go mod vendor
把依赖拷贝到 vendor/ 目录下
go mod verify
确认依赖关系
go mod why
解释为什么需要包和模块