golang包管理的方式有哪些?
- Golang包发展历史
官方推荐的有很多包管理方式:
主要有几种:
GOPATH、Godep、Glide、Govendor、GOModules
记住这几种
GOPATH < GO1.5 GOVendor >=GO1.5 GOModules >=GO1.11
GOPATH模式
go语言诞生就有 2009.11.10
通过统一包存放路径实现包管理
不支持依赖包的版本控制
GOPATH模式和GOPATH路径的区别?
GOPATH模式 通过GOPATH来管理包
GOPATH路径 GOPATH这个环境变量的路径
GOROOT和GOPATH的区别?
GOROOT是Golang的安装目录
GOPATH是Go语言指定的工作空间
注意:GOPATH跟GOROOT不能是同一个目录
GOPATH配置
~/.bash_profile(linux只对当前登录用户生效)文件或者/etc/profile文件
/ect/profile文件
export GOPATH= H O M E / u s e r g o p a t h e x p o r t G O B I N = HOME/usergopath export GOBIN= HOME/usergopathexportGOBIN=GOPATH/bin
export PATH= P A T H : PATH: PATH:GOBIN
开启了GOPATH模式下:
工程代码必须在GOPATH/src文件夹下面
go get命令
- 将远程代码克隆到$GOPATH/src目录下
- 执行go install 命令
- 可以指定-d命令参数仅下载不安装
go install 命令:
- 可执行和生成的二进制文件,存放在$GOPATH/bin下
- 普通包,编译生产的.a结尾的文件放到$GOPATH/pkg下
如何判断一个包是否生成二进制文件?
main包中存在main函数下的情况下,才能生成可执行文件
注意:go install是建立在GOPATH上的,无法单独使用
go install 命令:
是建立在GOPATH上的,无法单独使用
生成的可执行文件和包名一致
输出的目录是不支持通过命令指定的
思考:
为什么go get有 install还需要 一个单独的install指令?
go get是远程依赖包
本地包直接用 go install就可以
go build 命令:
默认是在当前目录下编译生成可执行文件,可以指定文件
不会将可执行文件复制到$GOPATH/bin目录下
go run 命令:
编译并运行go文件的
不依赖GOPATH
只能编译可执行的go文件
GOPATH目录
src存放源代码文件
pkg存放编译后的文件
bin存放编译后的可执行文件
Godep
2013年诞生,一个社区开发的第一个包管理工具
通过扫描并记录版本控制信息,再配合go命令加壳实现
源码存放在 Godeps/workspace/并作为GOPATH
缺点 没有解决依赖包问题
Glide
2014年诞生
通过glide.yaml记录包的版本依赖信息,glide.lock文件追踪每个包的具体修改
有点像node的里面的nvm
Govendor
2015年8月19日 GO15VENDOREXPREMIMENT=1开启
go 1.6默认开启
go 1.7作为功能支持,取消这个变量
本质 将源码拷贝到vendor目录并维护vendor.json文件,指定包版本
Govendor用法
安装 go get -u github.com/kardianos/govendor
初始化工程 govendor init
依赖包导入 vendor目录 govendor add + external
移除依赖 govendor remove + unused
依赖查找顺序: vendor目录(没有) ->GOPATH(没有)->(GOROOT)
缺点:包的依赖不能重用,包冗余度提升,冲突不能很好解决
- Go Modules
2018年 go1.11发布 GO111MODULE=on开启
1.13开始go modules默认启用
gomodules的用法:
on开启 Gomodules
off关闭
auto 根据项目是否在GOPATH目录决定
export GO111MODULE=on (unix环境)
set GO111MODULE=on windows
go env -w GO111MODULE=on
注意:除了这样开启管理,需要通过go mod init初始化工程文件
这样就成功建立了一个标准的go modules工程
go mod常用指令
go mod init 初始化
go mod tidy 可以增加依赖和移除本工程没有用的信息
go mod download 下载依赖包到本地缓存
go mod vendor 兼容go vendor模式
go.mod文件是什么时候生成的?有什么作用?有哪些内容?
go mod init的时候生成的
存放依赖信息
go.sum文件什么时候生成的?作用?内容?哈希值?包校验?
包伪版本号
v0.0.0-2015… -q111
版本号 UTF提交时间 哈希值前缀
包校验?
若有本地缓存有依赖包,计算包的hash并与go.sum记录对比
依赖包版本中任何一个文件(包括go.mod)都会改变hash值
校验的目的 保证项目所有依赖的那些模版版本不会被篡改
公网可下载的包回去GO校验数据库取模块的校验和
不会对依赖包进行哈希校验
GOPRIVATE匹配到的包 不走PROXY的代理 不会上传到github中的代码
打包到vendor目录中的包
GOSUMDB设置为off 关闭go sum校验
注意 同一模块版本的数据只缓存一份,所有其它模块共享使用
清除包缓存:go clean -modcache
为什么go.sum中版本数量会比go.mod多?
go.mod只在依赖包不含go.mod文件时,才会记录间接依赖包版本
go.sum则是要记录构建用到的所有依赖包版本
关闭依赖包校验
go env -w GOSUMDB =of
export GOSUMDB=off unix环境
依赖包存储目录 GOPATH模式下 依赖包 GOPATH/src
依赖包存储目录 GOMODULE模式下 依赖包 GOPATH/pkg/mod
构建go项目的一些原则和建议
一个目录名下只能有一个package
一个package名的内容放在一个目录下面
目录名和package名相同
- 发展历史总结
GOPATH go <1.5版本 2009.11.10
GOVendor go >=1.5版本 2015.8.19
GoModules go >=1.11版本 2018.8.24
- 如何使用内部包
internal文件夹包
internal控制包的可见性
go 1.4 可以使用internal文件限制包的导入权限
internal文件夹内的包只能被其父目录下的包或子包导入
内部开发的包
b本地包的方式导入 replace
通过私有仓库的方式导入