20

go mod的基础使用-科普

 4 years ago
source link: https://zhangguanzhang.github.io/2020/03/10/go-mod-base-use/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

文章主要是针对新人来介绍go mod是啥以及新手如何使用,老手不用看。现阶段go mod已经完全GA了,你会用了的话会非常方便

像python的项目根目录有 requirement.txt 记录依赖包,nodejs是 packages.json ,同样go的包管理从早期的go dep(gopkg)到vendor到现在的go mod.

go dep很早,没有接触过,如果你接触的项目有go dep,看完本文希望你可以学会改造你手上的老项目,vendor则是把包都存放项目的根路径的 vendor 文件夹里,就像下面。这会导致一个项目很大,多大40M以上。

$ tree -d -L 1
.
├── cert
├── cmd
├── docs
├── install
├── ipvs
├── net
├── pkg
├── test
├── vendor
└── version

go是一个开放的态度下诞生的语言,并没有其他语言那样官方维护一个中心库,go的库大多数都是直接github上的。

开发者把包存放到github上,一般打tag作为版本,master作为pr和修补,定期cut出新tag。这个做法和实际的开发流程一样。在这个环境下,go的包管理不可能单单存放一个版本号,所以 go.mod 是存放版本号, go.sum 记录git的hash值,以防止篡改。

这样并没有依赖包存在项目文件夹里导致项目代码体积过大,用户通过 go mod download 命令会调用git去拉取依赖,或者直接 go run 或者 go build 也会下载。

go mod如何使用

基础配置和相关环境变量

新手的话推荐使用1.13+版本的go,go mod是诞生于1.11版本,在1.13差不多定型了。1.12之前使用gomod的话需要配置环境变量 GO111MODULE=on ,这样才会开启go mod,而1.13以后默认变量为 auto ,会根据项目下的文件夹和文军自动识别是否是go mod。例如下面就是一个纯go mod项目

api/
docker/
models/
router/
service/
docs/
Dockerfile
go.mod
go.sum
main.go
README.md

如果之前用vendor由于依赖在本地,所以刚上手go mod的时候会发现 go get 拉取超时,实际上我们可以配置环境变量让go拉取包的时候走代理绕过墙,也就是配置 GOPROXY 。这个变量只有go mod启用下才能使用。

同时要注意的一点是,1.13+下 GOPROXY 能配置多个代理地址,下面是常见的地址

export GO111MODULE=on
export GOPROXY=https://goproxy.cn,https://mirrors.aliyun.com/goproxy/,https://goproxy.io,direct

direct是直连,用于内网开发拉取内网的私有库。默认拉取的时候会从前到后retry,也可以 GONOPROXY 配置某个不走代理

同时,也不要像以前以及网上的那些老视频教程那样把项目放在GOPATH上,现在GOPATH的概念越来越淡化了,不懂go mod下如果还是把项目创建在GOPATH下回容易出错。

同时也不要创建啥 src pkg bin 目录了,都是过去式了,可以看上面那个go mod的项目文件列表,压根没有src啥的。

终端编译或者run

配置了两个环境变量,项目也是go mod的话我们直接go run main.go或者build都会自动拉取包,不用担心墙

gomod和vendor共存

现在并不是所有用户都接受gomod,很多开源项目为了兼容新老用户,go mod和vendor都是有的,类似目录

...
vendor/
go.mod
go.sum
main.go

这样的项目我们编译的时候命令为

go build -mod vendor main.go

goland下的使用

分为新建项目和直接打开项目文件作为项目,不要把项目存放在 GOPATH

goland新建gomod开局项目

New Project 的时候选择 Go Modules(vgo) ,我们写 Proxy 就是 GOPROXY ,勾上 Vendoring mode 就是上面go mod和vendor共存的项目,如果你自己写新项目就不要勾选vendor了,vendor应该是过去式了。

goland打开一个项目,或者改造一个项目

如果是打开一个文件夹的项目,或者 New Project 的时候已经选择了 Go Modules(vgo) 上面的 Go ,我们需要配置下面

  • Settings –> GO –> GOPATH –> Project GOPATH下面如果不为空,就选中后点击右边的减号删掉
  • Settings –> GO –> Go Modules(vgo) 勾选 Enable Go Modules(vgo) integration ,写上Proxy

我们也可以终端操作

1.13 go mod init的话默认会以项目文件夹名为module名,例如下面

F:\go\Installer>go mod init
go: creating new go.mod: module Installer

执行后go.mod第一行为

module Installer

假如我们项目路径为

.
|-- api
|   |-- ks.go
|   `-- machine.go
|-- go.mod
|-- go.sum
|-- main.go

我们要在main.go里引用api包的话就写

import "Installer/api"

第一个就是go.mod里第一行的module名,不仅限于一个单词,有的人会以公司网站或者github地址,例如

module github.com/zhangguanzhang/Installer

这种名字下我们引用api就是

import "github.com/zhangguanzhang/Installer/api"

1.14开始 go mod init 后面必须接module名字

$ go mod init
go: cannot determine module path for source directory F:\go\test (outside GOPATH, module path must be specified)

Example usage:
        'go mod init example.com/m' to initialize a v0 or v1 module
        'go mod init example.com/m/v2' to initialize a v2 module

Run 'go help mod init' for more information.

有时候goland里设置改了不一定生效,所以我们得终端执行 go mod init 触发下,然后关闭goland,删除掉项目下的 .idea ,然后右击项目文件夹用goland打开。在设置里去配置下GOPROXY之类的。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK