【记录】Go 依赖管理配置

GOPATH

Go 安装完毕后,查看 Go 版本和环境变量

1
2
3
4
5
6
7
$ go version
go version go1.21.4 linux/amd64

$ go env -w GO111MODULE=auto
GO111MODULE=""
GOPATH=""
...

此时环境变量为默认值,GO111MODULE 默认值为空,实际对应是 on,即必须启用 Go modules,此时设置 GOPATH 不会生效。

设置 GO111MODULE=auto 后,GOPATH 下的本地包可以正常使用。

1
$ go env -w GO111MODULE=auto

但 Go1.11 后就开始逐步建议使用 Go modules,不再推荐 GOPATH 模式,因为有如下弊端:

  • 无版本控制概念:在执行go get时无法传达版本信息,即无法知道当前更新的版本。

  • 无法同步一致第三方版本号:在项目依赖库的管理上,无法保证所有人的依赖版本都一致。

  • 无法指定当前项目引用的第三方版本号:无法处理 v1、v2、v3 等不同版本的引用问题,因为 GOPATH 模式下的导入路径都是一样的(均为 github.com/foo/bar

所以现在重新设置 GO111MODULE=on,使用 Go Modules 模式进行依赖管理

1
$ go env -w GO111MODULE=on

Go Modules

镜像换源

Go 模块代理(Go module proxy)使 Go 在后续拉取模块版本时直接通过镜像站点来快速拉取,下面设置国内代理

1
2
# 七牛云,阿里云,direct
$ go env -w GOPROXY=https://goproxy.cn,https://mirrors.aliyun.com/goproxy/,direct

初始化

使用 Go Modules 的方式创建项目,为了与 GOPATH 分开,不要将项目创建在 GOPATH/src

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
$ mkdir -p $HOME/alfly/modules_test
$ cd $HOME/alfly/modules_test

# 初始化并定义当前项目的模块路径
$ go mod init github.com/alfly/modules_test
$ ls
---
go.mod  go.sum  main.go

$ vim main.go

远程包管理

作为测试的 main.go 内容如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package main

import (
	"fmt"
	"github.com/aceld/zinx/ziface"
	"github.com/aceld/zinx/znet"
)

// PingRouter MsgId=1 
type PingRouter struct {
	znet.BaseRouter
}

//Ping Handle MsgId=1
func (r *PingRouter) Handle(request ziface.IRequest) {
	//read client data
	fmt.Println("recv from client : msgId=", request.GetMsgID(), ", data=", string(request.GetData()))
}

func main() {
	//1 Create a server service
	s := znet.NewServer()

	//2 configure routing
	s.AddRouter(1, &PingRouter{})

	//3 start service
	s.Serve()
}
1
2
3
4
5
$ go get github.com/aceld/zinx/ziface
$ go get github.com/aceld/zinx/znet

$ ls $GOPATH/pkg/mod/github.com/aceld
zinx@v1.2.1

若要更新现有依赖的版本,可用如下命令修改模块的版本依赖关系

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ go mod edit -replace=zinx@v1.2.1=zinx@v1.2.0
$ cat go.mod
module github.com/alfly/modules_test

go 1.21.4

require (
        github.com/aceld/zinx v1.2.1 // indirect
        github.com/gorilla/websocket v1.5.0 // indirect
        github.com/klauspost/cpuid/v2 v2.1.1 // indirect
        github.com/klauspost/reedsolomon v1.11.8 // indirect
        github.com/pkg/errors v0.9.1 // indirect
        github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161 // indirect
        github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b // indirect
        github.com/tjfoc/gmsm v1.4.1 // indirect
        github.com/xtaci/kcp-go v5.4.20+incompatible // indirect
        golang.org/x/crypto v0.11.0 // indirect
        golang.org/x/net v0.12.0 // indirect
        golang.org/x/sys v0.10.0 // indirect
)

replace zinx v1.2.1 => zinx v1.2.0

本地包管理

进入项目目录,注意 vscode 打开的位置是当前项目的根目录

1
2
3
4
5
6
7
8
$ cd Web-Go
$ tree
.
├── module
│   ├── module.go
│   └── go.mod
├── go.mod
└── main.go

本地模块中初始化

1
2
3
4
5
6
7
$ cd ./module
$ go mod init module
$ cd ..
$ cat ./module/go.mod
module module

go 1.21.4

项目初始化(项目根目录中的 go.mod 文件中添加对本地模块的引用)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
$ go mod init github.com/Alfly/Web-Go

# 在 ./go.mod 中手动添加依赖
require module v0.0.0

# 使用本地模块
$ go mod edit -replace=module=./module
$ cat ./go.mod
module github.com/Alfly/Web-Go

go 1.21.4

require module v0.0.0
replace module => ./module

Go 1.18 引入了多模块工作区(配置 go.work 进行本地开发,项目发布不需要修改 go.mod 中的 replace

1
2
3
4
5
6
7
$ cat ./go.work
go 1.21

use (
	.
	module
)

Reference

0%