Golang 的包管理 —— go module

963

在编程时,我们经常会使用一些第三方依赖库。随着使用的依赖库越来越多,会出现一些问题,比如代码迁移困难,依赖库升级困难等问题,因此就出现了一系列包管理工具。比如 java 中经常使用的 Maven 和 Gradle 。

而 Go 语言也有自己的包管理机制。总的来说,Go 语言包管理机制经过了以下三个时期:

  • GOPATH

    直接在环境变量中设置 GOPATH 的路径,所有的包都放在这,使用 go get 可以直接将想要的包下载到 GOPATH 。不过这种模式不支持根据项目区分,所有项目都必须使用同一个 GOPATH 目录。虽然项目启动的时候会根据 import 自动获取对应包,但是不支持区分版本。

  • Go Vender

    govendor 是一个基于 vendor 机制实现的 Go 包依赖管理命令行工具。

    在 go 1.5 版本中提供支持,不过需要手动开启

    在 go 1.6 版本中默认开启

    在 go 1.7 版本中去除开关,强制开启

    当执行 go buildgo run 时会根据以下顺序查找要导入的包:

    • 当前包下 vender 文件夹
    • 向上级目录查找,直到来到 src/vender 文件夹
    • 在 GOROOT 中查找
    • 在 GOPATH 中查找

    使用中需要确保项目位于 GOPATH/src 中

  • Go module

    • go 1.11 中加入

    在项目根目录中新建 go.mod 文件,并根据文件加载对应包 。

    目前已受到社区的看好和强烈推荐,建议新项目采用 Go modules

GO111MODULE

在Go语言 1.12 版本之前,要启用 go module 工具首先要设置环境变量 GO111MODULE,不过在Go语言 1.13 及以后的版本则不再需要设置环境变量。通过 GO111MODULE 可以开启或关闭 go module 工具。

  • GO111MODULE=off 禁用 go module,编译时会从 GOPATH 和 vendor 文件夹中查找包;
  • GO111MODULE=on 启用 go module,编译时会忽略 GOPATH 和 vendor 文件夹,只根据 go.mod下载依赖;
  • GO111MODULE=auto(默认值),当项目在 GOPATH/src 目录之外,并且项目根目录有 go.mod 文件时,开启 go module。
命令说明
go mod download下载依赖
go mod edit编辑依赖
go mod graph打印依赖关系
go mod init初始化 go module - 创建 go.mod 文件
go mod tidy添加缺少的包,减少无用的包
go mod vendor将依赖复制到 vender 中
go mod verify效验依赖
go mod why为什么需要依赖

GOPROXY

可通过设置 GOPROXY 环境变量来切换 go 依赖包的镜像源。

目前公开的代理服务器的地址有:

  • goproxy.io;
  • goproxy.cn:(推荐)由国内的七牛云提供。

GO.MOD

先来看看一个 标准 的 go.mod

module WallhavenLI

go 1.16

require (
	github.com/PuerkitoBio/goquery v1.7.1
)

replace (
    golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a => github.com/golang/crypto v0.0.0-20190313024323-a1f597ede03a
)

分为四个模块,分别是

  • module 包名
  • go 指定 go 语言的版本
  • require 依赖包,url 和 版本
  • replace 切换包下载路径,例如 golang.org 下的包如果没有代理无法下载,可以使用 replace 切换到 github 中。

所有下载的包,都下载到 GOPATH/pkg/mod 中,在包名后,最后一个文件夹后面加入版本,可以支持多版本。