用过Java 的同学都知道,对依赖的管理经历了从原始的手动引入jar包,到使用maven等自动化管理工具去引入第三方依赖的过程,从而可以使用别人已经开发好的优秀工具。如果使用过Python的同学可能会熟练的使用pip install 第三方的工具包。Java 和Python的第三方工具包都是集中式管理的,使用maven 或者是pip 都是从对应的管理中心下载更新依赖。当然还有 npm、yarn、gradle等其他语言的依赖版本工具。
在go语言中,第三方依赖的管理工具经过了一个漫长的发展过程。在GO1.11 发布之前govendor、dep等工具百花齐放。直到go mod 出现,开始一统天下。go 的依赖非常简单粗暴,只要依赖源码就可以了。例如:
import "github.com/jinzhu/gorm"
github.com/jinzhu/gorm
就是gorm的GitHub项目路径。
GOPATH时期
Go 在1.11 之前使用GOPATH模式
进行依赖的管理。安装部署go环境,使用go 进行开发的时候强制被要求要设置GOPATH
(当然安装过程中也会默认指定$GOPATH=~/go
)。 要在GOPATH
路径下新建 src /bin /pkg
文件夹。
➜ ~/go
├── bin # 存储go编译生成的二进制可执行文件,一般会把该路径配置到PATH中,PATH=$PATH:$GOPATH/bin
├── pkg # 存储预编译的目标文件,以加快后续的编译速度
└── src # 存储Go的源代码,一般以$GOPATH/src/github.com/foo/bar的路径存放
➜ go go env |grep GOPATH
GOPATH="/Users/bytedance/go"
在这种模式下,如果使用go get
拉取外部依赖会自动下载并安装到$GOPATH/src
目录下。
这种模式下,go get
没有版本管理的概念,无法处理依赖不同版本的问题,因为同一个依赖都存在同一个路径下面。
在Go官方还没有推出Go Modules 的时候,go的依赖管理工具可谓是百花齐放,例如 govendor
, dep
,但是最终Go Modules发布,平息了诸侯割据的局面。
GO Modules
Go1.11 开始推出Go Modules ,Go1.13开始不再推荐使用GOPATH。意思就是说你可以在任何路径下存放你的Go源码文件, 不用再像以前一样非得放到$GOPATH/src
中。 每一个go项目 都是一个 Modules。vgo 是Go Modules的前身。
在Go Modules环境下出现了一个很重要的环境变量GO111MODULE
➜ ~ go env
GO111MODULE="auto"
GOPROXY="https://proxy.golang.org,direct"
GONOPROXY=""
GOSUMDB="sum.golang.org"
GONOSUMDB=""
GOPRIVATE=""
如果要对go 的环境变量进行设置,可以使用
go env -w GO111MODULE=on # 设置go 环境变量
go env -u # 恢复初始设置
GO111MODULE
GO111MODULE
这个环境变量是用来作为使用Go Modules 的开关。可以说这个变量是历史产物,很有肯能会在将来Go的新版本中去除掉。
GO111MODULE="auto" # 只要项目包含了go.mod 文件的话就启用Go modules, 在Go1.11-1.14 中是默认值
GO111MODULE="on" # 启用Go Modules
GO111MODULE="off" # 禁用Go Modules, 对老的项目进行兼容
GOPROXY
GOPROXY 是Go Modules的代理,可以通过镜像站点快速拉取(集中式的概念?),可以设置多个代理。
GOPROXY="https://proxy.golang.org,direct"
direct
的意思是如果通过代理获取不到go get 就会通过源地址直接去抓取
go mod
创建Go Modules的基本命令
➜ ~ 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.
# 所有的go commands 都支持 modules。
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.