Go Module管理
go的包搜索是从GOPATH和GOROOT目录开始的,源码要放在这两个目录的src下才能找到,从官方支持go modules开始,项目不需要放在GOPATH下,任意目录都可以。go mod是官方最新支持的包管理工具,1.11开始测试,1.12正式支持。目前来看,go mod代表着未来golang包管理方式,一定要学一下。
一:先看看mod有多少命令:
$ go mod help 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. Usage: go mod[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 " for more information about a command.
download | 下载依赖的module到本地cache缓存起来 |
edit | 编辑go.mod文件 |
graph | 打印模块需求图 |
init | 初始化模块,创建go.mod文件 |
tidy | 添加丢失的模块并删除未使用的模块 |
vendor | 在项目中创建 vendor 文件夹将依赖包拷贝过来 |
verify | 校验依赖 |
why | 解释为什么需要依赖 |
二:开启对mod支持
set GO111MODULE=on //windows export GO111MODULE=on //linuxGO111MODULE三个参数:
off:无模块支持,go 会从 GOPATH 和 vendor 文件夹寻找包。
on:模块支持,go 会忽略 GOPATH 和 vendor 文件夹,只根据 go.mod下载依赖。
auto:在 $GOPATH/src外面且根目录有 go.mod文件时,开启模块支持。
三:干
新建 F:\testgo //进入这个目录 go mod init testgo 初始化 模块名:testgo
初始化后看看发生了什么?目录下生成了一个文件:go.mod
module testgo go 1.12
文件里面有这么两句话!先不管了!
四:创建一个项目工程。
1:创建三个文件夹:src、pkg、bin文件夹
$ mkdir pkg bin src为什么要创建这三个文件夹?
bin:存放编译后的可执行文件;
pkg:存放编译后的包文件;
src:存放项目源文件。
bin和pkg目录也可以不创建,go命令会自动创建(如 go install)
2:在src目录建立main.go文件:
package main import( "github.com/sirupsen/logrus" ) func main(){ logrus.Debug("88888") }进入src目录,运行构建,看能不能把logrus给搞下来,正常加载。
go build竟然报错,因为golang.org被墙了,我朝访问不到。
修改go.mod代码,设置代理从github上面搞。
module testgo go 1.12 replace ( golang.org/x/sys => github.com/golang/sys latest )再次构建
$ go build go: finding github.com/golang/sys latest go: downloading github.com/konsorten/go-windows-terminal-sequences v1.0.1 go: extracting github.com/konsorten/go-windows-terminal-sequences v1.0.1成功了!
再看看go.mod文件发生了什么?
可以看到 mod干了三件事:
1:把logrus依赖给搞下来了
2:给当前这个依赖加了版本号,红色部分
3:把当前的依赖“包含”了进来
这里有个疑问!go mod把依赖下载到哪里去了?
目前为止还是在 $GOPATH/pkg/mod中。
我们可以看一下:运行:go env 查看一下我们的$GOPATH指到哪里的。
我的GOPATH是:F:\gowww
刚才下载下来的这个文件
缓存在这里
3:加载本地包文件
我在src里面建一个lib目录,假设这里面都是自己写的一些公用的go文件。
lib里面我随便建立一个文件a.go
package bar import "fmt" func Abc() { //首字母要dax fmt.Print("This is test print\n") }然后在main.go中载入进来
package main import( "github.com/sirupsen/logrus" "testgo/src/lib" //这就进来了 testgo是模块名称 ) func main(){ bar.Abc() //调用a.go的这个函数 首字母要大写 logrus.Debug("88888") }运行一下:
$ go run main.go This is test printOK!
注意:虽然这样能够找到,但是项目结构不明朗,其实这里a.go命名为bar.go更清晰。
再看一个命令:go mod vendor
$ go mod vendor go: downloading github.com/golang/sys v0.0.0-20190813064441-fde4db37ae7a go: extracting github.com/golang/sys v0.0.0-20190813064441-fde4db37ae7a看看发生了什么?
发现多了这个目录,mod所有的依赖都复制了一份到这里里面。
4:显示import信息:go list -m -json all
$ go list -m -json all { "Path": "vendor", "Main": true, "Dir": "F:\\go", "GoMod": "F:\\go\\go.mod", "GoVersion": "1.12" } { "Path": "github.com/gomodule/redigo", "Version": "v2.0.0+incompatible", "Time": "2018-03-14T22:34:43Z", "Dir": "F:\\gowww\\pkg\\mod\\github.com\\gomodule\\redigo@v2.0.0+incompatible", "GoMod": "F:\\gowww\\pkg\\mod\\cache\\download\\github.com\\gomodule\\redigo\\@v\\v2.0.0+incompatible.mod" }只有一个,redigo,go的redis驱动,logrus已经被移除了。