Go mod 开发中常用玩法 -- 开发必备

AnthonyDong · · 936 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

什么是go mod

go modules 是 golang 1.11 新加的特性。

那么问题来了,它解决了什么问题,其实核心的问题就是,他可以没有GoPath这个概念,所以很方便,但是当你不会使用的时候,你会觉得它很不好用。

​ PS:go.mod文件一旦创建后,它的内容将会被go toolchain全面掌控。go toolchain会在各类命令执行时,比如go get、go build、go mod等修改和维护go.mod文件。

简单使用

比如,现在有一个需求是,我们要创建一个新项目,项目名字为 go-kit-demo,此时我们需要go-kit的依赖,那么怎么办呢

第一步

% mkdir go-kit-demo

% cd go-kit-demo

% go mod init go-kit-demo // 初始化一个项目名为 go-kit-demo,这个路径其实是你相对于GOPATH的路径,以后你的包就是 import "go-kit-demo/util" 之类的

% ls
go.mod // 发现多了个文件

% cat go.mod
module go-kit-demo // 模块名字

go 1.13 // go版本

% go mod edit -require=github.com/go-kit/kit@latest //添加go-kit的依赖

% go mod download //下载依赖

% cat go.mod
module go-kit-demo

go 1.13

require github.com/go-kit/kit v0.10.0 // indirect

% ls
go.mod    go.sum//校验包
复制代码

第二步,其实就是需要代码,让编辑器可以找到,显然目前go官方不支持的,需要第三方。

​ 但是这里你无法直接使用go-kit,理由是,goland工具不支持,这种模块依赖,所以必须引入到vendor中,也就是。

这里推荐一个工具,他可以将依赖打包到vendor进去,相当nice

https://github.com/nomad-software/vend
复制代码

根据要求来就行了

go get github.com/nomad-software/vend
复制代码

就像下面这样子

~/go/code/mode-test % vend
vend: copying cloud.google.com/go (v0.34.0)
vend: copying github.com/BurntSushi/toml (v0.3.1)
vend: copying github.com/Knetic/govaluate (v3.0.1-0.20171022003610-9aa49832a739+incompatible)
vend: copying github.com/Shopify/sarama (v1.19.0)
vend: copying github.com/Shopify/toxiproxy (v2.1.4+incompatible)
vend: copying github.com/VividCortex/gohistogram (v1.0.0)
vend: copying github.com/afex/hystrix-go (v0.0.0-20180502004556-fa1af6a1f4f5)
vend: copying github.com/alecthomas/template (v0.0.0-20190718012654-fb15b899a751)
vend: copying github.com/alecthomas/units (v0.0.0-20190717042225-c3de453c63f4)
vend: copying github.com/apache/thrift (v0.13.0)
vend: copying github.com/armon/circbuf (v0.0.0-20150827004946-bbbad097214e)
复制代码

所以还是很方便的,可以将依赖全部copy到vendor下,就可以愉快的使用了。

其他命令

比如说国内源的问题,需要修改一下

export GOPROXY=https://goproxy.cn
复制代码

其次就是,比如低版本的go ,可能需要强制开启go mod

export GO111MODULE=on
复制代码

像其他命令我就不介绍了,比如还有常用的可能就是go mod vendor,将依赖copy到vendor目录下,但是有个问题就是,它只会copy代码依赖的东西,所以我们有些时候是不方便的,因此,需要使用到我上面推荐的工具。

比如说

go get github.com/go-kit/kit //此时会在go.mod文件中添加依赖,也就是说不需要手动的去执行 go mod edit -require=github.com/go-kit/kit@latest了
复制代码

还有其他命令

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//编辑go.mod
	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 // copy到vendor
	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 提供了module, requirereplaceexclude 四个命令

  • module 语句指定包的名字
  • require 语句指定的依赖项模块
  • replace 语句可以替换依赖项模块
  • exclude 语句可以忽略依赖项模块

其实这些不需要care

本地仓库如何解决

需求,我们现在有另外一个项目,我们这个项目需要引入。

​ PS: 进入公司,一般你会将公司的代码,放在同一个目录下面,也就是上一级目录是一样的,所以我们也遵守这个规范,理由其实很简单,因为方便环境。

初始化 A\B项目,名字为 demo-1,demo-2

~/go/code/test % cd demo-1
~/go/code/test/demo-1 % ls
~/go/code/test/demo-1 % go mod init demo-1
go: creating new go.mod: module demo-1
复制代码

我们目前目录结构是这样的:

~/go/code/test % tree .
.
├── demo-1
│   └── go.mod
└── demo-2
    ├── api
    │   └── userservice.go
    └── go.mod

3 directories, 3 files
复制代码

我们现在demo-1这个项目,需要使用 user-service这个接口

package api

type UserService interface{
	GetUserInfo()*UserInfo
}

type UserInfo struct{
	Name string `json:"name"`
	Age  int  `json:"age"`
}
复制代码

此时只需要在 demo-1里面做一下替换就可以了,如下图所示

module demo-1

go 1.13

require demo_2 v0.0.0

replace demo_2 => ../demo-2
复制代码

然后我们demo-1就可以愉快的使用了

package main

import (
	"demo_2/api"
	"fmt"
)

func main() {
	info := api.UserInfo{
		Name: "tom",
		Age:  18,
	}
	fmt.Println(info)
}
复制代码

那么现实中,可能依赖包要更新,需要及时的拉去master,这个更新怎么办,很简单,只需要执行 go mod vendor 从新拉去一下

​ 注意的一点是 本地包,无法校验hash

为什么要必须使用vendor目录

  • 1、依赖可能是本地,可能是私有仓库,无法解决
  • 2、生产环境可能拉去慢
  • 3、没有通用的解决方案,等go以后发展吧

其中 go build -mod=vendor 的意思是强制开启vendor模式,依赖只会去vendor目录找,其他都不会care,也不会网络环境找。

私人仓库如何解决

全部公有仓库,没啥事,但是私有怎么半

这三个方案,理论上都可行,但是都有缺陷。

goproxy代理,本身并不解决从gitlab服务器获取私有项目代码的问题,也没有成熟的鉴权机制。因此比较适合静态公共代码。

​ 例子可以看:goproxy.cn/

nginx代理,同样不解决认证的问题,我配置了一个代理,ssl认证失败(弱鸡本鸡),理论上这个方案是最好的解决方案。

go replace,需要在每个项目中都添加,更新依赖也比较复杂。

所以采用的方案是,还是本地依赖。

目前网上的解决方案都是修改本地的git,配置,通过配置一些信息之类的,自行百度,但是还是又问题。最好还是搭建代理比较好,从代理层解决,可以参考上面的go proxy。


有疑问加站长微信联系(非本文作者)

本文来自:掘金

感谢作者:AnthonyDong

查看原文:Go mod 开发中常用玩法 -- 开发必备

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

936 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传