Go的依赖管理

2022-04-05 GoLang 大约 3 分钟

早期的Go语言被很多开发者所吐槽的一个问题就是没有依赖包的管理,不过随着版本的不断更迭,Go语言依赖管理方面也在不断的完善。

最初的时候Go语言所依赖的所有的第三方包都放在 GOPATH 目录下面,这就导致了同一个包只能保存一个版本的代码,如果不同的项目依赖同一个第三方的包的不同版本,应该怎么解决呢?

相关信息

GOPATH的默认路径:

  • unix/linux:~/go
  • windows::%USERPROFILE%\go

# GOPATH

使用GOPATH来管理依赖

  1. 创建一个新项目,目录结构如下:

    demo
    └── src
        └── proj1
    
    1
    2
    3
  2. 设置环境变量

    # 不要使用这种方式,它会覆盖掉全局的GOPATH。主要是因为这是我临时建立的目录,做演示的
    go env -w GOPATH=D:\demo
    go env -w GO111MODULE=off
    
    # 建议使用
    export GOPATH=D:\demo
    expot GO111MODULE=off
    
    1
    2
    3
    4
    5
    6
    7
  3. 在项目proj1中下载依赖:

    $ go get -u go.uber.org/zap
    
    1
  4. 目录结构:

    demo
    └── src
        ├── go.uber.org
        └── proj1
    
    1
    2
    3
    4

    可以看到下载的包在 src 目录中。

  5. 使用包

    // 创建 proj1/main.go
    package main
    
    import (
    	"go.uber.org/zap"
    )
    
    func main() {
    	log, _ := zap.NewProduction()
    	log.Warn("我输出了")
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

当我们的src下有多个项目的时候,每个项目项目又有不同版本的zap,那么我们可以在每个项目中新建vendor目录,然后手动把下载的依赖移动到此目录中,那么go会优先从此目录查找依赖。

由于每个项目都有自己的vendor目录,来存放第三方库,所以就有了后来的第三方依赖管理工具:glide、dep、go dep等。

# godep

godep 是一个Go语言官方提供的通过 vender 模式来管理第三方依赖的工具,类似的还有由社区维护的准官方包管理工具 dep。

Go语言从 1.5 版本开始开始引入 vendor 模式,如果项目目录下有 vendor 目录,那么Go语言编译器会优先使用 vendor 内的包进行编译、测试等。

详细内容请查看原文:传送门 (opens new window)

# go module

go module 是Go语言从 1.11 版本之后官方推出的版本管理工具,并且从 Go1.13 版本开始,go module 成为了Go语言默认的依赖管理工具。

特点:

  • 由go命令统一管理,用户不必关心目录结构。
  • 初始化:go mod init
  • 增加依赖:go get
  • 更新依赖:go get [@v...],go mod tidy
  • 将就项目迁移到go modgo mod init、go build ./...

# 使用

  1. 创建一个新项目awesomeProject1

  2. 设置环境变量:GO111MODULE=on

  3. 初始化 go.mod

    $ go mod init
    
    awesomeProject1
    └── go.mod     
    
    1
    2
    3
    4
  4. 下载依赖

    # 下载成功后,会生成一个go.sum文件,里面保存着依赖的地址和版本。
    $ go get -u go.uber.org/zap
    
    1
    2
  5. 新建main.go文件

    package main
    
    import (
    	"go.uber.org/zap"
    )
    
    func main() {
    	log, _ := zap.NewProduction()
    	log.Warn("下午好")
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

相关信息

此时下载的包依赖在 GOPATH/pkg/mod/go.uber.org中,也就是说go mod下载的依赖都会被管理在pkg/mod中

# 注意事项

如果你在go get时出现以下错误

$ go get -u go.uber.org/zap
go get: module go.uber.org/zap: Get "https://proxy.golang.org/go.uber.org/zap/@v/list": dial tcp 142.251.43.17:443: connectex: A connection attempt failed because the connected party d
id not properly respond after a period of time, or established connection failed because connected host has failed to respond.
1
2
3

解决:设置代理,然后重新执行 go get

$ go env -w GOPROXY=https://goproxy.cn
1
上次编辑于: 2023年7月4日 09:36