Golang | 依赖管理-01:Go Modules 初步了解和学习
Contents
Go1.11 新特性 — 依赖管理工具:Go Modules 初步学习和使用笔记,内容包括:
- 简单了解下
Go Module
以及一些新概念 - 简单了解下
go mod
命令
1. Go Module
Go1.11 添加了对版本化模块的初步支持,版本化模块的提案在这里
Go 模块 是 Go 1.11 中选择加入的一个实验性功能,希望结合反馈并最终确定Go 1.12的功能。即使细节可能会发生变化,未来版本也会支持使用Go 1.11或vgo定义的模块。
-
通常我们会在一个 repo(仓库) 中创建一组 Go package,repo 的路径比如:github.com/myrepo/demo 会作为 go package 的导入路径(import path),Go 1.11给这样的一组在同一repo下面的packages赋予了一个新的抽象概念:
module
,并启用一个新的文件go.mod
记录 module 的元信息。…
接下来,我们了解几个新概念…
1.1. 新概念
这部分内容来自官网:Wiki Modules, 对部分内容做了简要翻译.
1.1.1. Modules
A module is a collection of related Go packages that are versioned together as a single unit. Most often, a single version-control repository corresponds exactly to a single module, but alternatively a single version-control repository can hold multiple modules.
一个模块就是把相关联的 Go 包作为单个单元一起版本化的集合。通常,单个版本控制仓库与单个模块是完全对应的,但是单个版本控制仓库也可以包含多个 modules
Modules must be semantically versioned
(语义化版本) in the form v(major).(minor).(patch), such as v0.1.0, v1.2.3, or v3.0.1. The leading v is required. If using Git, tag
released commits with their versions. (Optional privately hosted and public globally hosted “always on” immutable(不可变的) repositories such as Project Athens are in the works).
Note: 关于版本化
- Modules 必须是语义化版本,格式:
v<v.m.p>
, 其中主版本号 v 必须存在- 在使用 Git 作为版本控制的项目中,项目发布记录的 tag 号也可以用作它们的版本
- 一个 Repo 下可以拥有多个 modules
1.1.2. go.mod
A module is defined by a tree of Go source files with a go.mod
file in the tree’s root directory. Module source code may be located outside of $GOPATH.
一个模块是由Go源文件树定义,且在源文件树的根目录下包含了一个 go.mod 文件。模块源代码可能位于 $GOPATH 之外。
Note:
- go.mod 文件的作用:记录 module 的元信息,属于文本文件
- 使用了 Go Module 后,源码不一定要在 GOPATH 中进行
All of the packages in a module share a common prefix – the module path. The go.mod file defines the module
path via the module
directive. For example, if you are defining a module for two packages example.com/my/thing/foo and example.com/my/thing/bar, the first line in your go.mod file typically would be module example.com/my/thing
.
Module files may include comments and will look familiar to a Go programmer. Here is an example go.mod file:
|
|
这里有四个指令可以使用:module、require、exclude、replace
- require: 语句指定的依赖项模块
- replace: 语句可以替换依赖项模块
- exclude: 语句可以忽略依赖项模块
关于 exclude & replace
更详细的介绍请到原文查阅
1.1.3. Version Selection
If you add a new import to your source code that is not yet covered by a require in go.mod, any go command run (e.g., 'go build'
) will automatically look up
the proper module and add the highest version of that new direct dependency to your module’s go.mod
as a require directive. For example, if your new import corresponds to dependency M whose latest tagged release version is v1.2.3, your module’s go.mod will end up with require M v1.2.3, which indicates module M is a dependency with allowed version >= v1.2.3 (and < v2, given v2 is considered incompatible with v1).
这部分讲的是 go module 会自动更新 go.mod 文件,并将依赖关系写入其中…
1.1.4. Semantic Import Versioning
这部分内容主要是关于语义导入版本控制的,详细内容可在原文查阅
1.2. 特性开关 GO111MODULE
现在 modules 机制仍在早期阶段,所以golang提供了一个环境变量 GO111MODULE
,默认值为auto,如果当前目录里有go.mod文件,就使用go modules,否则使用旧的GOPATH和vendor机制,因为在modules机制下go get只会下载go modules,这一行为会在以后版本中成为默认值,这里我们保持auto即可,如果你想直接使用modules而不需要从GOPATH过度,那么把 GO111MODULE
设置为on。
2. Go Module 命令:go mod
Go mod provides access to operations on modules.
Usage:
1
|
go mod <command> [<arguments>] |
The commands are:
1 2 3 4 5 6 7 8 |
download download modules to local cache // 下载模块到本地缓存 edit edit go.mod from tools or scripts // 从工具或脚本来编辑 go.mod(记录module元信息的文件) graph print module requirement graph init initialize new module in current directory // 在当前目录初始化新的 module,会生成 go.mod 文件 tidy add missing and remove unused modules // 添加丢失的或移除不再使用的 modules vendor make vendored copy of dependencies // 将依赖包复制到项目下的 vendor 目录 verify verify dependencies have expected content why explain why packages or modules are needed |
Use “go help mod
Others usefull:
1 2 |
go list -m all 显示依赖关系 go list -m -json all 显示详细的依赖关系 |
3. See Also
Thanks to the authors 🙂