[学习笔记] Go Modules 使用

我们为什么要使用 Go Modules?

  • 在不借助任何额外工具的情况下,依赖包只能手动下载。
  • 手动下载第三方包也没有版本的概念。
  • 需要配置 GOPATH,协同开发需要统一依赖包。
  • 如果使用的包引用了其他已经转移的包,需要自己修改。
  • 第三方包和自己开发的包都在 GOPATH 下的 src 目录,比较混乱。

使用了 Go Modules 之后?

  • 依赖包自动下载。
  • 会给第三方包标上准确的版本号。
  • 项目根目录下会自动生成 go.mod 文件,列出依赖。
  • 对于转移了的包,可以使用 replace 特性进行替换。
  • 项目可以放在 GOPATH 下的 src 目录之外的地方。

以下是我配置使用 Go Modules 的过程

第一步

  • 先确保您的 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/go

mkdir hello-golang && cd hello-golang

vim main.go

package main

import "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-project
    go 1.12

    第三步

  • 尝试依赖一下第三方包,这里以 iris 为例。
  • 修改 main.go 文件,键入如下 iris-demo。
    package main
    import "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-project
    go 1.12
    require (
    github.com/BurntSushi/toml v0.3.1 // indirect
    github.com/Joker/jade v1.0.0 // indirect
    github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398 // indirect
    github.com/aymerick/raymond v2.0.2+incompatible // indirect
    github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385 // indirect
    github.com/fatih/structs v1.1.0 // indirect
    github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4 // indirect
    github.com/gorilla/schema v1.1.0 // indirect
    github.com/iris-contrib/blackfriday v2.0.0+incompatible // indirect
    github.com/iris-contrib/formBinder v5.0.0+incompatible // indirect
    github.com/iris-contrib/go.uuid v2.0.0+incompatible // indirect
    github.com/json-iterator/go v1.1.7 // indirect
    github.com/kataras/golog v0.0.0-20190624001437-99c81de45f40 // indirect
    github.com/kataras/iris v11.1.1+incompatible // indirect
    github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d // indirect
    github.com/klauspost/compress v1.8.3 // indirect
    github.com/klauspost/cpuid v1.2.1 // indirect
    github.com/microcosm-cc/bluemonday v1.0.2 // indirect
    github.com/ryanuber/columnize v2.1.0+incompatible // indirect
    github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
    golang.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 下完成替换。

本作品采用《CC 协议》,转载必须注明作者和本文链接
Hello。
讨论数量: 1
yanrui

@icecho :kissing_heart:

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!