Go Modules – Golang 依赖管理的使用介绍

之前使用 go build, go install, go run 都需要显式的设置环境变量 GOPATH。代码的组织结构也需要按照 GOPATH 的约定来。否则在编译时,会报找不到

如果引入了第三方包,发现需要从 GOROOT, GOPATH 中找。

在之前的开发中,在编译过程中,会显式的设置 GOPATH,而且需要 go get 包时,也需要显式的设置下。如果存在多个项目的话,第三方包也要放到项目下的,导致项目的代码比较多。

Modules 特性从 golang 1.11 版本开始引入,成为了官方依赖管理的方案。Modules 使我们脱离了 GOPATH 的限制,在 GOPATH 之外可以编译代码,逐渐淡化 GOPATH 的使用。

当前来说,GOPATH 还是必要的,使用 go mod 下载的包还需要放在 \$GOPATH/pkg/mod 下面。包括二进制文件还是下载到 \$GOPATH/bin 下。

让我们通过示例说明 go mod 的使用。

简单的项目

设置的 $GOPATH=/home/bruceding/projects/go, 而代码目录为 /home/bruceding/hello, 项目代码是在 $GOPATH 之外的。

在目录 hello 下创建 hello.go 文件

当我们直接 build 时, go build hello.go, 报错

说明还是之前的方式依据 $GOPATH 编译。

使用 go mod 的方式,执行 go mod init github.com/bruceding/hello

可以看到了 go.mod 文件,我们定义了一个 module ,名称为 github.com/bruceding/hello。

我们运行下编译

可以看到编译成了,而且自动下载了第三方包,而且第三方包的依赖也下载下来了。在当前文件生成了 hello 执行文件。

复杂些的例子

在项目下创建 util.go 文件

Hello.go 中直接使用 调用 Hello 函数。直接编译运行

但是我们运行 go build hello.go , 发现

报错了。这个时候,需要把 hello.go 用到的所有文件一同编译, go build hello.go util.go 才可以。

假设目录下有两个包含 main 函数的文件

这个时候,不能直接用 go build 编译了,需要指定 main 函数的文件及其依赖。

多本地包的应用

新建 utils 目录,把 util.go 移动进去,然后需要改成 package utils。然后修改 hello.go

我们看到,在 import 的时候,utils 和之前的 $GOPATH 是不同的,是根目录下 go.mod 定义的 module + 相应的包目录名称。

依赖包放到项目本地

有时候我们会把第三方包放到本地目录,有时会在第三方包中插入调试代码,或者有修改的需求。

通过 go mod vendor, 会把依赖包放到本地。本地会自动创建 vendor 目录。编译时增加 mod 参数即可, go build -mod vendor

多项目应用

有时候,同一个 repo 下有个项目,项目有各自的 local package, 也会公用 local package。代码结构组织如下

我们测试的目录树如下

其中有两个 utils 包,一个是主 module 的, 一个是子 module的。在 project1 目录中,执行 go mod init 初始化

然后修改 hello.go 文件,让其对两个 utils 都 import。

当我们编译时,反而会报错了

可以把 module 想象成一个上下文,在子 module 中,是找不到主 module 的。这时,要显式的设置路径,让子 module 能找到主 module。

这样就可以成功了。

此条目发表在GO分类目录,贴了标签。将固定链接加入收藏夹。

发表评论

电子邮件地址不会被公开。