Golang依赖管理工具之go module(go1.11)

大多数语言都会有包管理工具,像Node有npm,PHP有composer,Java有MavenGradle

可是,Go语言一直缺乏一个官方的包管理(Dep被称为官方试验品official experiment)。

终于,在go1.11 版本中,新增了module管理模块功能,用来管理依赖包。

要知道,在这个之前,想要对go语言包进行管理,只能依赖第三方库实现,比如Vendor,GoVendor,GoDep,Dep,Glide等等,对于初学者来说,真的是选择困难症。

关于Workspaces和GOPATH

go1.11 之前,如果不使用第三方包管理工具可行,就是直接使用go get安装第三方包。

工作空间Workspaces,是Go项目的根目录,也就是

GOPATH是GO项目必备的环境变量,用来存放Go的开发代码和第三方包代码,代码需要按照一定的目录安排。

指定GOPATH路径:

$ echo $HOME
/Users/wangtom
$ export GOPATH=$HOME/goworkspace

查看GOPATH:

$ go env |grep GOPATH                    
GOPATH="/Users/wangtom/goworkspace"

开启module特性

要开始使用 go module 的特性, 需要先设置 GO111MODULE 环境变量。

开启 GO111MODULE

要使用go module,首先要设置GO111MODULE=on,这没什么可说的,如果没设置,执行命令的时候会有提示,这个大家应该都了解了。

创建模块

创建一个新的模块mytest:

模块命名为github.com/cnwyt/mytest,就是我们创建的GitHub仓库的路径,方便我们以后提交代码。

按照原来GOPATH开发模式,创建新的包需要放置在$GOPATH/src/github.com

创建一个目录mytest目录,并进入该命令:

$ mkdir -p $GOPATH/src/github.com/cnwyt/mytest
$ cd $GOPATH/src/github.com/cnwyt/mytest

使用 go mod init 命令初始化该模块,提示错误:

$ go mod init mytest                                                                                            
go: modules disabled inside GOPATH/src by GO111MODULE=auto; 
see 'go help modules'

开启 GO111MODULE:

这是因为,默认设置的GO111MODULE=auto, 导致 modules 默认在 GOPATH/src 路径下是不启用的。
如果需要在 GOPATH/src 也能使用modules, 需要把 GO111MODULE 环境变量设置为 on.

$ export GO111MODULE=on  
$ go mod init github.com/cnwyt/mytest   
go: creating new go.mod: module github.com/cnwyt/mytest

当然这个go模块可以创建在任意位置,不强制邀请放在GOPATH路径下。
下边我们再创建一个

调用go modules:

在GOPATH以外的模块,创建一个helloworld目录,用来调用刚刚创建的mytest模块。

$ mkdir helloworld && cd helloworld
$ vi main.go

创建一个main.go文件:

package main

import "fmt"
//import "github.com/cnwyt/mytest"

func main() {
    fmt.Println("Hello, World!");

    //mytest.ShowTest1()
}

初始化该模块,引入github.com/cnwyt/mytest模块,指定版本为latest:

$ go mod init helloworld
$ go mod edit -require github.com/cnwyt/mytest@latest

初始化后,会生成一个go.mod文件,类似npm里的package.json或者composer的composer.json的一个文件。

module helloworld

require github.com/cnwyt/mytest v0.0.0

这样直接执行go test 或者 go run main.go 会报错:

$ go test
build helloworld: cannot find module for path github.com/cnwyt/mytest

这是为啥呢? 这是因为我们虽然创建了一个名为github.com/cnwyt/mytest模块,在GOPATH路径里也有这个模块。但是,GO模块去Github去找这个模块,而不是在GOPATH路径里去找,所以找不到。

那该怎么办呢?
有两个解决办法:
第一个办法,很简单,就是直接将cnwyt/mytest模块推送的GitHub上。
但是,如果我要修改cnwyt/mytest里的代码,都得先推送到GitHub上,才能生效,实在太麻烦了。
那就直接使用第二个办法, 使用 go replace:

直接修改go.mod,新增一行replace:

module helloworld

require github.com/cnwyt/mytest v0.0.0

replace github.com/cnwyt/mytest => /Users/wangtom/goworkspace/mytest

注意版本号必须填写,可以填v0.0.0或者latest.

然后重新运行即可:

$ go test                                                    
go: finding github.com/cnwyt/mytest v0.0.0
?   	helloworld	[no test files]

备注: 因为本地没有*_test.go测试文件,所以会有提示"no test files".
这里运行go test也只是让go module去拉取最新的模块.

调用第三方模块

比如项目中会用到比较流行的路由模块 gorilla/mux:

直接修改go.mod,新增一行require,不指定版本可以直接写latest获取最新版本:

require github.com/gorilla/mux latest

运行 go buildgo test 会自动从GitHub下载模块,并会修改 go.mod 文件。

比如运行后会把 latest 直接修改成目前最新的版本 v1.6.2 :

module helloworld

require github.com/cnwyt/mytest v0.0.0
require github.com/gorilla/mux v1.6.2

replace github.com/cnwyt/mytest => /Users/wangtom/goworkspace/godict

可以看到模块gorilla/mux代码会下载到 $GOPATH/pkg/mod/ 模块下:

$ ll /Users/wangtom/goworkspace/pkg/mod/github.com/gorilla 
total 0
dr-xr-xr-x  22 wangtom  staff 704B 12 24 22:14 [email protected]

[END]

你可能感兴趣的:(Golang)