oynix

于无声处听惊雷,于无色处见繁花

go mod命令

mod,即module,golang的模块管理工具。Node.js有npm,Python有pip,Golang现在也有了go mod。

起因是,许久不写go了,前几天拿到一个go写的项目,发现里面依赖管理已经不是早前的方式,而多了一张新面孔,go.mod文件,趁此机会了解学习一下。

原文在这

简介

如果配置过golang开发环境,应该还记得GOPATH这个环境变量,指向一个目录,这个目录下有三个子目录,bin、pkg和src,我们写的代码都在src里,除此之外,所依赖的模块也在src目录下,我们在依赖别人的同时,也可以成为别人的依赖,这是官方给的建议,可能他们觉得一家人就是要整整齐齐的,这是最早期的包管理机制。如果我们开发了10个项目工程,那么这10个项目的所有依赖都在这里面,你中有我,我中有你,随着项目增多,这个目录会越来越大。

但是,每个依赖模块都是有着不同版本,多个工程会存在依赖不同版本的情况,共享GOPATH下的项目,就变得难以操作,于是就衍生出了vendor。每个工程下都有个叫vendor的子目录,直接翻译就是供货商的意思,项目所有的依赖都放到各自的vendor子目录中,互不干涉,互不影响。我的印象中,就是这种管理机制,使用godep命令来管理依赖,这个是当时最实行的方式,毕竟go module还没问世呢。

随着时间发展,技术的进步,go module出来了,它比vendor多了依赖版本记录管理的功能,同时也提升了其他一些vendor体验不好的功能,比如依赖包升级,这些都写在了go.mod文件里,这个文件就和Node.js里的package.json、Python里的requirements.txt功能是一样的。此外,go mod还提供了一个特性,就是项目工程可以不再放在GOPATH/src下了,这样就可以不被其他项目所依赖。

go mod 使用

执行一下go mod,就可以看到命令的说明了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$ go mod
Go mod provides access to operations on modules.

Note that support for modules is built into all the go commands,
not just 'go mod'. For example, day-to-day adding, removing, upgrading,
and downgrading of dependencies should be done using 'go get'.
See 'go help modules' for an overview of module functionality.

Usage:

go mod <command> [arguments]

The commands are:

download download modules to local cache
edit edit go.mod from tools or scripts
graph print module requirement graph
init initialize new module in current directory
tidy add missing and remove unused modules
vendor make vendored copy of dependencies
verify verify dependencies have expected content
why explain why packages or modules are needed

Use "go help mod <command>" for more information about a command.

常用的有这几个

  • go mod init:初始化,一般创建新工程后使用
  • go mod tidy:更新项目依赖,没有的下载,没用的删除
  • go mod vendor:创建vendor目录,并将依赖复制至此目录

添加新依赖,其中branch指定版本

1
go get github.com/repo/package@branch

GO111MODULE 说明

这是个环境变量,有3个可选值:off、on和auto,用来控制go modules功能,看这个名字就知道,是在1.11版本添加的

  • off:关闭,编译时仍旧是用老方式,也就是GOPATH/src,或者vendor中的依赖
  • on:开启,编译时不会在GOPATH/src下找依赖,而是使用项目中的go.mod文件,依赖包放在pkg/mod下,多项目共享缓存的modules,项目名后面跟着@符号以及版本号
  • auto:默认值,在1.13之后,如果工程下存在go.mod文件,则自动开启。1.11中,工程需要在src之外的目录才会开启,以确保兼容

go build -mod 说明

上面有提到,GOPATH/pkg下是生成的中间包.a文件,编译时它的优先级最高,也就是最先被查找,如果找到目标依赖的中间包,则不会再去编译源文件从而再生成.a中间包。

mod有3个值,readonly、vendor和mod。

  • readonly:所需依赖不在go.mod中时,或checksum不在go.mod中时,则报错。
  • vendor:将使用vendor下的package,而不是pkg/mod下的,不会检查go.mod中的版本
  • mod:这个mod就是pkg/mod,也就是用会使用pkg/mod中的package,不存在则下载对应版本的package

附录:go build 和 go install

go build是用来编译、在项目目录下生成可执行的文件,每一个package main都会在相同位置生成一个可执行文件,但不会生成包文件,也就是pkg下的文件。

go install则是用来生成库和工具。没有package main的包,编译后的文件会放到pkg对应的名称下,扩展名.a,如果有package main,就会生成可执行文件,并放到GOPATH/bin下。

所以,二者的相同点是都会生成可执行文件,不同点是生成位置不同,同时instal还会生成中间包文件.a。

------------- (完) -------------
  • 本文作者: oynix
  • 本文链接: https://oynix.com/2022/04/012444d8e7c5/
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

欢迎关注我的其它发布渠道