go中的包管理
在看一个旧项目的时候,让把项目放到
GOPATH/src下,为了解决这个疑惑。看了一些与GOPATH相关的介绍而整理。
包管理
Go在 Go1.11后解决了包管理的相关问题。之前比较依赖GOPATH与GOROOT的环境变量,因此在之前的项目中,都是放到GOPATH/src的目录下,现在比较流行的 go mod解决了很多问题。有以下特点:
✅ 一个版本只存一份:所有项目共享同一版本的包,下载一次,多处个项目都可以使用
✅ 版本隔离:不同版本可以并存
✅不再像之前一样依赖
GOPATH
存储的位置由$GOMODCACHE决定
go get
在 go1.11之前的功能:
下载源码到 GOPATH
编译并安装到 $GOPATH/bin
在 go1.11+:
添加依赖到 go.mod
下载依赖(下载到了模块缓存中
go env GOMODCACHE)不安装二进制文件(与之前不同,现在需要使用
go install主动安装)
go get与go mod download的区别
go mod download只下载,go get下载并修改go.mod
go install
go install 与之前的旧版go get功能基本一致,是下载并安装包并安装,下载过程与现在go get一致。
当不带路径时:
安装当前目录(及子目录)的main包
可执行文件安装到 $GOBIN 或 $GOPATH/bin
带包路径时:
安装指定的远程包
可执行文件安装到 $GOBIN 或 $GOPATH/bin
go.mod及正常流程
download:将go.mod文件中所有标明的依赖下载到本地缓存edit:编辑go.mod文件,它提供的命令行接口主要是提供给其它工具或脚本调用的。init:在当前目录初始化一个 gomod 项目tidy:分析项目依赖,修改go.mod,下载缺失的依赖,删除无用的依赖graph:输出依赖图verify:验证本地的依赖why:解释为什么会依赖这些模块vendor:导出项目依赖到 vendor 目录
正常项目的启动流程:
go mod download下载依赖使用
go build(当入口项目)或者go build ./...(需要构建多个包的多服务项目)会按需对 download 的包进行编译
如果某个项目修改一个公用包的源码,怎么办?
Go Modules 的缓存目录
$GOMODCACHE是只读的,不推荐修改,修改完后完整性校验会失败。推荐使用的方法有三种
# 方法1:需要修改时,使用 replace 将包指向自己本地的目录 git clone https://github.com/gin-gonic/gin ~/dev/gin-fork go mod edit -replace github.com/gin-gonic/gin=../gin-fork vim ~/dev/gin-fork/gin.go # 方法2: fork一个自己的仓库(略) # 方法3: 是用 vendor 模式 # 1. 创建 vendor 目录 go mod vendor # 2. 修改 vendor 中的代码 vim vendor/github.com/gin-gonic/gin/gin.go # 3. 使用 vendor 模式 go build -mod=vendor