Go Mod依赖管理以及Go Work工作区管理 | 青训营

1,048 阅读4分钟

1. Go Mod

Go Module 的基本概念是将每个项目作为一个模块(module),并有独立的模块路径。每个模块都可以包含多个包(package),并且每个模块都有一个 go.mod 文件来记录包依赖关系。

Go Module允许开发者在项目的任意目录中独立管理依赖,而不再需要将项目放在 GOPATH 下。这个变化使得 Go 语言更加现代化和灵活,也避免了在 GOPATH 下进行全局的代码共享带来的一些问题。

准备工作

使用 Go Module 需要满足以下条件:

  1. Go 1.11 及以上版本。
  2. 需要将环境变量 GO111MODULE 设置为 on,这样才能启用 Go Module 功能。
  3. !!踩坑!! 如果使用的是IDEA,需要在Settings中开启Go Module功能

image.png

image.png

常见用法

在一个项目中启用 Go Module 后,可以通过以下步骤进行包依赖管理:

image.png

  1. 在项目根目录下执行 go mod init 模块路径 命令来初始化一个新的模块。例如:go mod init myapp 将会创建一个名为 myapp 的模块,并生成一个默认的 go.mod 文件。
  2. 执行 go get 指令下载依赖并保存到 go.mod 文件。在 Go 1.11 之前,项目源代码和依赖都存放在 %GOPATH%/src 目录中,而在 Go Module 模式下,项目源代码可以存放在任意目录,依赖存放在 %GOPATH%/pkg/mod 目录。
  3. 执行 go mod tidy 命令可以分析代码中的依赖关系,并更新当前模块的 go.mod 文件。这个命令会根据代码中的实际引用,自动添加和删除模块的依赖关系。

依赖搜索顺序

Go Module 系统在寻找依赖时的搜索顺序如下:

  1. 项目本身目录: Go Module 会首先查找项目根目录中的依赖。如果你的项目路径中有某个依赖的代码,Go Module 就会直接使用这个路径下的依赖。
  2. Go Module Cache: 如果项目本身目录中没有找到依赖,Go Module 会尝试从 Go Module Cache 中查找。这是一个全局的缓存,用于存储所有项目的依赖。如果你之前执行过 go get 等命令来下载依赖,依赖应该会被存放在 Go Module Cache 中。

常见命令

在使用 Go Module 进行包依赖管理时,还有一些其他常用的命令和功能:

  • go mod init: 初始化一个新的模块。
  • go get: 下载指定模块的源代码,并添加到当前模块的依赖关系。
  • go list: 列出当前模块的所有依赖项。
  • go build / go run: 构建或运行包含 Go Module 的项目。
  • go mod edit: 编辑 go.mod 文件,手动添加、删除或更新依赖项。
  • go mod graph: 显示模块之间的依赖关系图。
  • go mod verify: 验证模块的依赖项已经完整下载并且没有被篡改。
  • go mod vendor:将所有依赖项复制到项目的 vendor 目录中。这样可以确保项目的构建过程中使用的是 vendor 目录中的依赖项,而不是全局的 GOPATH 下的依赖项。

其他

另外还有一些 Go Module 的注意事项:

  • go.sum文件:当第一次运行 “go build” 或 “go test” 命令时,将安装所有依赖包的特定版本,同时会创建 go.sum 文件,用于维护校验和。(再次运行同一项目,不会再次安装依赖包)
  • require 语句:go.mod 文件中的 require 会包含项目中所有依赖模块以及对应版本,如果存在若干个Module,使用了不同的依赖版本,那么 %GOPATH%/pkg/mod 内会保存所有用到的版本。这也有利于依赖的版本管理。
  • replace 语句:go.mod 文件中的 replace 指向依赖包的本地版本,通过创建远程版本的本地拷贝,无需从远程进行安装
  • //indirect:项目并不直接使用这些依赖包,而是存在传递性依赖

go work

"Go Work" 是 Go 1.18 版本中引入的一个新特性,它是一种多模块工作区管理方法,旨在改善大型项目的依赖管理。在之前的版本中,Go 语言使用单一的 go.mod 文件来管理整个项目的依赖,但在大型项目中,这可能会导致依赖冲突和管理困难。

"Go Work" 允许你在项目中使用多个 go.work 文件,每个文件对应一个子模块,可以独立地管理依赖和版本。这有助于将大型项目分解为更小的模块,每个模块可以有自己的依赖管理。这个特性旨在改善大型项目的可维护性和依赖管理,减少全局依赖的影响。

使用 "Go Work" 时,每个子模块都有自己的目录,其中包含了一个 go.work 文件和一个或多个 go.mod 文件。在主工作区目录下,也有一个顶层的 go.work 文件。每个 go.work 文件会包含一组子模块的列表,以及指定如何构建这些子模块。

  • go work init

    初始化工作区文件,用于生成 go.work 工作区文件

  • go work use

    添加新的模块到工作区,模块必须是 go mod 依赖管理的仓库