- 在不借助任何额外工具的情况下,依赖包只能手动下载。
- 手动下载第三方包也没有版本的概念。
- 需要配置 GOPATH,协同开发需要统一依赖包。
- 如果使用的包引用了其他已经转移的包,需要自己修改。
- 第三方包和自己开发的包都在 GOPATH 下的 src 目录,比较混乱。
- 依赖包自动下载。
- 会给第三方包标上准确的版本号。
- 项目根目录下会自动生成 go.mod 文件,列出依赖。
- 对于转移了的包,可以使用 replace 特性进行替换。
- 项目可以放在 GOPATH 下的 src 目录之外的地方。
第一步
- 先确保您的 golang 版本大于等于 1.12。
go version//go version go1.12.9
- 添加环境变量 GO111MODULE。
要注意这里 GO111MODULE 可设置为三种值:
- auto 自动模式,如果项目在 $GOPATH/src里,就会使用 $GOPATH/src 的依赖包,在$GOPATH/src之外,就会使用 go.mod 里 require 的包。
- on 开启模式,go 1.12 后,无论项目是不是在 $GOPATH/src 里,都会使用 go.mod 里 require 的包。
- off 关闭模式,就是原始的样子啦。
// 这里我使用的是 fish shell,配置命令如下 vim ~/.config/fish/config.fish添加 set -x GO111MODULE on
第二步
- 在 $GOPATH/src 路径外,我们尝试创建一个项目。
cd ~/www/gomkdir hello-golang && cd hello-golangvim main.gopackage mainimport "fmt" func main() { fmt.Println("Hello, golang!")}go mod init my-first-go-project
- 运行完上面的命令之后,项目根目录下会生成一个 go.mod 文件,是一个包管理文件。
官方说明:除了 go.mod 之外,go 命令还维护一个名为 go.sum 的文件,其中包含特定模块版本内容的预期加密哈希go 命令使用 go.sum 文件确保项目所依赖的模块不会出现意外更改,无论是出于恶意、意外还是其他原因。 go.mod 和 go.sum 都应检入版本控制。但是这里 go.sum 不需要手工维护,所以可以不用太关注。
- 查看一下 go.mod 文件。
cat go.mod// 可以看到模块名称以及 go 的版本号module my-first-go-projectgo 1.12
第三步
- 尝试依赖一下第三方包,这里以 iris 为例。
- 修改 main.go 文件,键入如下 iris-demo。
package mainimport "github.com/kataras/iris"func main() {app := iris.Default()app.Get("/ping", func(ctx iris.Context) { ctx.JSON(iris.Map{ "message": "pong", })})app.Run(iris.Addr(":8080"))}
- 按照以前的传统方法,应该要先 go get 安装 iris 到 $GOPATH/src,但是现在我们不用这么做啦。
- 直接运行如下命令,它会自动检查代码中依赖的包,自动下载,并且把依赖关系以及版本写入 go.mod 以及 go.sum 中。
go run main.go
这里如果遇到了超时的问题,需要添加 GOPROXY 环境变量,可参考 GOPROXY 官网进行配置。
- 运行成功之后,我们再次查看 go.mod 文件
cat go.mod//module my-first-go-projectgo 1.12require (github.com/BurntSushi/toml v0.3.1 // indirectgithub.com/Joker/jade v1.0.0 // indirectgithub.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398 // indirectgithub.com/aymerick/raymond v2.0.2+incompatible // indirectgithub.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385 // indirectgithub.com/fatih/structs v1.1.0 // indirectgithub.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4 // indirectgithub.com/gorilla/schema v1.1.0 // indirectgithub.com/iris-contrib/blackfriday v2.0.0+incompatible // indirectgithub.com/iris-contrib/formBinder v5.0.0+incompatible // indirectgithub.com/iris-contrib/go.uuid v2.0.0+incompatible // indirectgithub.com/json-iterator/go v1.1.7 // indirectgithub.com/kataras/golog v0.0.0-20190624001437-99c81de45f40 // indirectgithub.com/kataras/iris v11.1.1+incompatible // indirectgithub.com/kataras/pio v0.0.0-20190103105442-ea782b38602d // indirectgithub.com/klauspost/compress v1.8.3 // indirectgithub.com/klauspost/cpuid v1.2.1 // indirectgithub.com/microcosm-cc/bluemonday v1.0.2 // indirectgithub.com/ryanuber/columnize v2.1.0+incompatible // indirectgithub.com/shurcooL/sanitized_anchor_name v1.0.0 // indirectgolang.org/x/crypto v0.0.0-20190911031432-227b76d455e7 // indirect)
- 到这里,使用 Go Modules 的一个小 Demo 就完成啦。
你可能想知道?
包去哪了?使用 Go Modules 方式管理第三方包,第三包都被下载到了 $GOPATH/pkg/mod 目录下。
版本怎么控制?版本可以在 go.mod 中指定,如果没有指定默认依赖最新版。可用 require 语句来依赖指定包以及版本。
地址失效了怎么修复?在 go.mod 文件中运用 replace 来替换第三方包,例如
replace golang.org/x/text => github.com/golang/text latest
这样就可以完成包的替换,它就会拉github.com/golang/text 的最新版到 $GOPATH/pkg/mod/golang.org/x/text 下完成替换。