基于go module方式管理包(package)

news/2024/11/15 9:51:38/文章来源:https://www.cnblogs.com/yinzhengjie/p/18302301

目录
  • 一.Go Modules发展史
    • 1 前言
    • 2 早期第三方包存储在GOPATH路径
    • 3 vendor阶段
    • 4 社区管理工具层出不穷
    • 5 go modules官宣官方管理工具
  • 二.go module介绍
    • 1 GO111MODULE环境变量
    • 2 GOPROXY
    • 3 GOSUMDB
    • 4 GONOPROXY/GONOSUMDB/GOPRIVATE
    • 5 go.mod文件
    • 6 go.sum文件
    • 7 依赖保存位置
  • 三. 3.go module常用命令
    • 1 "go mod"常用的子命令概述
    • 2 使用go module引入包第三方包
      • 2.1 初始化项目
      • 2.2 下载第三方程序包
    • 3 代码测试
      • 3.1 项目组织结构
      • 3.2 blog.go源代码
      • 3.3 main.go源代码
      • 3.4 运行项目并访问WebUI

一.Go Modules发展史

1 前言

一般编程语言都会提供依赖库管理工具,例如python的pip、node.js的npm,java的maven,rust的cargo,Go语言也有提供自己的依赖库管理工具。Go语言在1.11提出了Go mod,每次版本或多或少都会对go.mod进行改进优化,go mod也越来越好,当前大多数公司都使用go mod来管理依赖库。考虑新手很容易在"go module"使用上犯迷糊,本篇文章主要介绍"Go Modules"发展史及快速入门的必要知识点。

2 早期第三方包存储在GOPATH路径

起初Go语言在1.5之前没有依赖管理工具,若想引入依赖库,需要执行go get命令将代码拉取放入GOPATH/src目录下。这样的依赖管理方式存在一个致命的缺陷,那就是不支持版本管理,同一个依赖包只能存在一个版本的代码。可是我们本地的多个项目完全可能分别依赖同一个第三方包的不同版本。

3 vendor阶段

为了解决隔离项目的包依赖问题,Go1.5版本推出了vendor机制,环境变量中有一个GO15VENDOREXPERIMENT需要设置为1,该环境变量在Go1.6版本时变成默认开启,目前已经退出了历史舞台;vendor其实就是将原来放在"GOPATH/src"的依赖包放到工程的vendor目录中进行管理,不同工程独立地管理自己的依赖包,相互之间互不影响,原来是包共享的模式,通过vendor这种机制进行隔离,在项目编译的时候会先去vendor目录查找依赖,如果没有找到才会再去GOPATH目录下查找。vendor阶段的优劣势:优点:保证了功能项目的完整性,减少了下载依赖包,直接使用vendor就可以编译缺点:仍然没有解决版本控制问题,go get仍然是拉取最新版本代码。

4 社区管理工具层出不穷

很多优秀的开发者在这期间也都实现了不错的包依赖管理工具,例如:godep:https://github.com/tools/godepgovendor:https://github.com/kardianos/govendorglide:https://github.com/Masterminds/glidedep:https://github.com/golang/depdep应该是其中最成功的,得到了Go语言官方的支持,该项目也被放到了https://github.com/golang/dep,但是为什么dep没有称为官宣的依赖工具呢?其实因为随着"Russ Cox"与"Go团队"中的其他成员不断深入地讨论,发现dep的一些细节似乎越来越不适合Go,因此官方采取了另起"proposal(建议)"的方式来推进,其方案的结果一开始先是释出”vgo“,最终演变为我们现在所见到的”Go modules“;

5 go modules官宣官方管理工具

go modules是"Russ Cox"(Go语言核心开发团队人员之一)推出来的,发布于Go1.11。go modules成长于Go1.12,丰富于Go1.13,正式于Go1.14推荐在生产上使用。go modules几乎后续的每个版本都或多或少的有一些优化,比如在Go1.16引入go mod retract、在Go1.18引入go work工作区的概念。参考连接:https://www.cnblogs.com/yinzhengjie/p/18142081

二.go module介绍

1 GO111MODULE环境变量

这个环境变量是"Go Modules"的开关,主要有以下参数:auto:只在项目包含了go.mod文件时启动go modules,在Go1.13版本中是默认值。on:无脑启动Go Modules,推荐设置,Go1.14版本以后的默认值。off:禁用Go Modules,一般没有使用go modules的工程使用。我现在使用的Go版本是1.22.4,默认GO111MODULE=on。

2 GOPROXY

这个环境变量主要是用于设置Go模块代理"Go module proxy",其作用是用于使Go在后续拉取模块版本时能够脱离传统的VCS方式,直接通过镜像站点来快速拉取。GOPROXY的默认值是"https://proxy.golang.org,direct",由于某些原因国内无法正常访问该地址,所以我们通常需要配置一个可访问的地址。目前社区使用比较多的有两个"https://goproxy.cn"和"https://goproxy.io",当然如果你的公司有提供GOPROXY地址那么就直接使用。设置GOPAROXY的命令如下:# go env -w GOPROXY=https://goproxy.cn,directGOPROXY允许设置多个代理地址,多个地址之间需使用英文逗号","分隔。最后的"direct"是一个特殊指示符,用于指示Go回源到源地址去抓取(比如"GitHub"等)。当配置有多个代理地址时,如果第一个代理地址返回"404"或"410"错误时,Go会自动尝试下一个代理地址,当遇见"direct"时触发回源,也就是回到源地址去抓取。

3 GOSUMDB

该环境变量的值是一个Go checksum database,用于保证Go在拉取模块版本时拉取到的模块版本数据未经篡改。若发现不一致会中止,也可以将值设置为off即可以禁止Go在后续操作中校验模块版本;什么是Go checksum database?Go checksum database主要用于保护Go不会从任何拉到被篡改过的非法Go模块版本,详细算法机制可以看一下:https://go.googlesource.com/proposal/+/master/design/25530-sumdb.md#proxying-a-checksum-databaseGOSUMDB的默认值是sum.golang.org,默认值与自定义值的格式不一样,默认值在国内是无法访问,这个值我们一般不用动,因为我们一般已经设置好了GOPROXY,goproxy.cn支持代理sum.golang.org;GOSUMDB的值自定义格式如下:- 格式1:<SUMDB_NAME>+<PUBLIC_KEY>。- 格式2:<SUMDB_NAME>+<PUBLIC_KEY> <SUMDB_URL>。

4 GONOPROXY/GONOSUMDB/GOPRIVATE

这三个环境变量放在一起说,一般在项目中不经常使用,这三个环境变量主要用于私有模块的拉取。在GOPROXY、GOSUMDB中无法访问到模块的场景中,例如拉取git上的私有仓库。GONOPROXY、GONOSUMDB的默认值是GOPRIVATE的值,所以我们一般直接使用GOPRIVATE即可,其值也是可以设置多个,以英文逗号进行分割。"GOPRIVATE"用来告诉"go"命令哪些仓库属于私有仓库,不必通过代理服务器拉取和校验。"GOPRIVATE"的值也可以设置多个,多个地址之间使用英文逗号","分隔。我们通常会把自己公司内部的代码仓库设置到"GOPRIVATE"中,例如:$ go env -w GOPRIVATE="git.yinzhengjie.com" 这样在拉取以"git.yinzhengjie.com"为路径前缀的依赖包时就能正常拉取了。此外,如果公司内部自建了"GOPROXY"服务,那么我们可以通过设置"GONOPROXY=none",允许从内部代理拉取私有仓库的包。也可以使用通配符的方式进行设置,对域名设置通配符号,这样子域名就都不经过Go module proxy和Go checksum database;

5 go.mod文件

go.mod是启用Go modules的项目所必须且最重要的文件,其描述了当前项目的元信息,每个go.mod文件开头符合包含如下信息:module:用于定义当前项目的模块路径(突破$GOPATH路径)。go:当前项目Go版本,目前只是标识作用、require:用设置一个特定的模块版本,可以指定需要依赖的版本号。Go modules中建议使用语义化版本控制,其建议的版本号格式如下:主版本号:发布了不兼容的版本迭代时递增(breaking changes)。次版本号:发布了功能性更新时递增。修订号:发布了bug修复类更新时递增。exclude:用于从使用中排除一个特定的模块版本。replace:用于将一个模块版本替换为另外一个模块版本。 比如将一个无法访问的域名替换成国内的镜像站点或者本地路径均可。retract:用来声明该第三方模块的某些发行版本不能被其他模块使用,在Go1.16引入。如果某个发布的版本存在致命缺陷不再想让用户使用时,我们可以使用retract声明废弃的版本。indirect:行尾的indirect表示该依赖包为间接依赖,说明在当前程序中的所有"import"语句中没有发现引入这个包。

6 go.sum文件

使用go module下载了依赖后,项目目录下还会生成一个go.sum文件。这个文件中详细记录了当前项目中引入的依赖包的信息及其hash 值。go.sum文件内容通常是以类似下面的格式出现。- <module> <version>/go.mod <hash>- <module> <version> <hash>- <module> <version>/go.mod <hash>不同于其他语言提供的基于中心的包管理机制,例如“npm”和“pypi”等,Go并没有提供一个中央仓库来管理所有依赖包,而是采用分布式的方式来管理包。为了防止依赖包被非法篡改,Go module引入了go.sum机制来对依赖包进行校验。

7 依赖保存位置

"go mod download"会将依赖缓存到本地,Go module缓存的目录是"$GOPATH/pkg/mod/cache“、"GOPATH/pkg/sum"。这些缓存依赖可以被多个项目使用,未来可能会迁移到$GOCACHE下面。每个依赖包都会带有版本号进行区分,这样就允许在本地存在同一个包的多个不同版本。温馨提示:如果想清除所有本地已缓存的依赖包数据,可以执行"go clean -modcache"命令。 

三. 3.go module常用命令

1 "go mod"常用的子命令概述

命令 介绍
go mod init 初始化项目依赖,生成go.mod文件
go mod download 根据go.mod文件下载依赖
go mod tidy 比对项目文件中引入的依赖与go.mod进行比对
go mod graph 输出依赖关系图
go mod edit 编辑go.mod文件
go mod vendor 将项目的所有依赖导出至vendor目录
go mod verify 检验一个依赖包是否被篡改过
go mod why 解释为什么需要某个依赖
Go module 是 Go1.11 版本发布的依赖管理方案,从 Go1.14 版本开始推荐在生产环境使用,于Go1.16版本默认开启。如上表所示,Go module 提供了以上命令供我们使用,我们可以使用“go help mod”查看可以使用的命令。Go语言在"go module"的过渡阶段提供了"GO111MODULE"这个环境变量来作为是否启用"go module"功能的开关。考虑到Go1.16之后 "go module"已经默认开启,所以本书不再介绍该配置,对于刚接触Go语言的读者而言完全没有必要了解这个历史包袱。

2 使用go module引入包第三方包

2.1 初始化项目

	1.初始化项目
yinzhengjie@bogon 02-crm % pwd
/Users/yinzhengjie/golang/gosubjects/src/gocode/devops/05-package/02-crm
yinzhengjie@bogon 02-crm % 
yinzhengjie@bogon 02-crm % ls -l
total 0
yinzhengjie@bogon 02-crm % 
yinzhengjie@bogon 02-crm % go mod init web-server
go: creating new go.mod: module web-server
yinzhengjie@bogon 02-crm % 
yinzhengjie@bogon 02-crm % ls -l                 
total 8
-rw-r--r--@ 1 yinzhengjie  staff  29  7 14 23:00 go.mod
yinzhengjie@bogon 02-crm % 
yinzhengjie@bogon 02-crm % cat go.mod 
module web-servergo 1.22.4
yinzhengjie@bogon 02-crm % 2.go.mod内容说明:
module web-server:定义当前项目的导入路径。go 1.22.4:标识当前项目使用的go版本。温馨提示:go.mod文件会记录项目使用的第三方依赖包信息,包括包名和版本,由于我们的"web-server"项目目前还没有使用到第三方依赖包,所以go.mod文件暂时还没有记录任何依赖包信息,只有当前项目的一些信息。

2.2 下载第三方程序包

	1.安装gin框架
yinzhengjie@bogon 02-crm % go get -u github.com/gin-gonic/gin2.查看本地
yinzhengjie@bogon 02-crm % ls -l
total 24
-rw-r--r--@ 1 yinzhengjie  staff  1376  7 14 23:17 go.mod  # 依赖文件
-rw-r--r--@ 1 yinzhengjie  staff  7028  7 14 23:17 go.sum  # 依赖包的校验文件
yinzhengjie@bogon 02-crm % 
yinzhengjie@bogon 02-crm % cat go.mod  # 关于go.mod的文件内容解析请参考上文中的介绍哟~
module web-servergo 1.22.4require (github.com/bytedance/sonic v1.11.9 // indirectgithub.com/bytedance/sonic/loader v0.1.1 // indirectgithub.com/cloudwego/base64x v0.1.4 // indirectgithub.com/cloudwego/iasm v0.2.0 // indirectgithub.com/gabriel-vasile/mimetype v1.4.4 // indirectgithub.com/gin-contrib/sse v0.1.0 // indirectgithub.com/gin-gonic/gin v1.10.0 // indirectgithub.com/go-playground/locales v0.14.1 // indirectgithub.com/go-playground/universal-translator v0.18.1 // indirectgithub.com/go-playground/validator/v10 v10.22.0 // indirectgithub.com/goccy/go-json v0.10.3 // indirectgithub.com/json-iterator/go v1.1.12 // indirectgithub.com/klauspost/cpuid/v2 v2.2.8 // indirectgithub.com/leodido/go-urn v1.4.0 // indirectgithub.com/mattn/go-isatty v0.0.20 // indirectgithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirectgithub.com/modern-go/reflect2 v1.0.2 // indirectgithub.com/pelletier/go-toml/v2 v2.2.2 // indirectgithub.com/twitchyliquid64/golang-asm v0.15.1 // indirectgithub.com/ugorji/go/codec v1.2.12 // indirectgolang.org/x/arch v0.8.0 // indirectgolang.org/x/crypto v0.25.0 // indirectgolang.org/x/net v0.27.0 // indirectgolang.org/x/sys v0.22.0 // indirectgolang.org/x/text v0.16.0 // indirectgoogle.golang.org/protobuf v1.34.2 // indirectgopkg.in/yaml.v3 v3.0.1 // indirect
)
yinzhengjie@bogon 02-crm %  温馨提示:1.在执行go get命令下载一个新的依赖包时一般会额外添加"-u"参数,强制更新现有依赖;2.行尾的indirect表示该依赖包为间接依赖,说明在当前程序中的所有"import"语句中没有发现引入这个包;3.下载软件包的名称和版本使用"@"区分,若不指定版本则默认会下载最新的发布版本;

3 代码测试

3.1 项目组织结构

image-20240714233756124

如上图所示,是我随意找的目录,做的目录组织结构,其中包括引入第三方包和本项目中自定义包引入。

3.2 blog.go源代码

package blogimport (// 导入第三方仓库代码"github.com/gin-gonic/gin"
)func StartWebServer() {// 创建一个默认的路由引擎r := gin.Default()// GET:请求方式;/hello:请求的路径// 当客户端以GET方法请求/hello路径时,会执行后面的匿名函数r.GET("/hello", func(c *gin.Context) {// c.JSON:返回JSON格式的数据c.JSON(200, gin.H{"name": "尹正杰","blog": "https://www.cnblogs.com/yinzhengjie",})})// 启动HTTP服务,默认在0.0.0.0:8080启动服务r.Run()
}

3.3 main.go源代码

package mainimport (// 注意,此处的"web-server"是"go.mod文件中记录的"module web-server"对应的名称哟~// 而"web-server"下对应的"blog"是我们自定义的包名哟~"web-server/blog"
)func main() {blog.StartWebServer()
}

3.4 运行项目并访问WebUI

image-20240714234121979

如上图所示,我们可以正常访问咱们自定义的项目啦~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/743774.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

rsync+inotify数据的实时同步

一、实时同步技术介绍 1.工作原理:要利用监控服务(inotify),监控同步数据服务器目录中信息的变化发现目录中数据产生变化,就利用rsync服务推送到备份服务器上2.inotify 异步的文件系统事件监控机制,利用事件驱动机制,而无须通过诸如cron等的轮询机制来获取事件,linux内…

Mysql在数据插入后立即获取插入的Id

项目中有需要再数据插入后实用插入的Id,这里使用的是useGeneratedKeys什么是useGeneratedKeys? 官方的说法是该参数的作用是:“允许JDBC支持自动生成主键,需要驱动兼容”,如何理解这句话的意思?其本意是说:对于支持自动生成记录主键的数据库,如:MySQL,SQL Server,此…

03_spark_RDD算子

Transformation 转换算子 RDD 整体上分为 Value、双Value、Key-Value 三种类型。 Value 类型 Map算子函数签名 def map[U:ClassTag](f:T=>U):RDD[U],它通过接受一个参数,并且遍历该 RDD 中每一个数据项,依次应用函数 f 并得到新的 RDD;object Value01_map {def main(arg…

启动数据分析软件SPSS17遭遇的两弹窗解决方案

问题描述 朋友请我帮她安装 SPSS17 这款软件,我寻思这是啥软件,谷歌一下,发现是一个数据分析工具。 在一系列的下一步、确定后,打开时,第 1 个惊喜弹窗来了: 【弹窗内容】应用程序无法启动,因为应用程序的并行配置不正确。有关详细信息,请参阅应用程序事件日志,或使用…

HackChat匿名聊天室

匿名聊天聊天室地址 这是一款极简、无干扰的聊天应用程序,可以让你专注于交流而不必担心干扰. 频道通过 url 创建、加入和共享,通过更改问号后的文本来创建自己的频道. hack.chat 服务器上不会保留任何消息历史记录,链接断开消息就会删除. 使用教程 欢迎使用 hack.chat,这是…

通过MATLAB分别对比二进制编码遗传优化算法和实数编码遗传优化算法

1.程序功能描述通过MATLAB分别对比二进制编码遗传优化算法和实数编码遗传优化算法,对比最优适应度值,平均适应度值以及算法运算效率。2.测试软件版本以及运行结果展示 MATLAB2022a版本运行3.核心程序%-10~10,初始化种群 Popu = 6*rand(NUM,dim)-3; %初始化最优适应度值 Vb…

【CICID】GitHub-Actions-SpringBoot项目部署

目录【CICID】GitHub-Actions-SpringBoot项目部署0 流程图1 创建SprinBoot项目1.1 项目结构1.2 Dockerfile文件2 云服务器环境搭建2.1 安装docker2.2 获取IP、账号、密码3 Github配置3.1 配置密码3.2 创建Action3.2 action代码4 触发5 效果5.1 查看Action信息5.3 云服务器5.3.1…

使用Visual Studio诊断工具检查内存泄漏——订阅Events

参考文章 8 Ways You can Cause Memory Leaks in .NET订阅事件导致内存泄漏的原因 订阅事件后,该对象将保留对你的类的引用。除非你使用不捕获类成员的匿名方法。 防止Event内存泄漏的方法注销订阅事件。 使用弱句柄(weak-handler)模式。 如果可能,请使用匿名函数进行订阅,…

Jetpack Compose(9)——嵌套滚动

自定义 Composable 组件 目录一、Composable 组件渲染流程1.1 组合1.2 布局1.3 绘制二、自定义组合三、自定义布局3.1 LayoutModifier (自定义 View)3.2 Layout (自定义 ViewGroup)3.3 固有特性测量Intrinsic3.3.1 使用内置组件的固有特性测量3.3.2 自定义固有特性测量3.4 …

ACCESS 用普通按钮控制导航窗体-子窗体中的显示目标

Forms!控制面板!NavigationSubform.SourceObject = "目标窗体"注: 在导航窗体的属性面板中不会显示SourceObject属性,但它是真实存在的.

ECMA标准ECMAScript(JavaScript的一个标准)和C#

2024 年 6 月 26 日,第 127 届 ECMA 大会正式批准了 ECMAScript 2024 语言规范,这意味着它现在正式成为最新 ECMAScript 标准。ECMAScript是ECMA标准中最著名的编程语言标准,它定义了JavaScript语言的核心特性。C#语言则是由ECMA国际组织制定的编程语言标准,目前最新的版本…

CAD、GIS与Three.js如何完美结合,实现2D与3D数据可视化的无限可能

CAD、GIS与Three.js是热门的三大软件或技术,如何将三都完美结合起来,实现2D与3D数据可视化的无限可能呢?现状 AutoCAD是全球最流行的CAD软件之一,其生成的DWG文件格式已经成为二维绘图的事实标准格式。然而,由于AutoCAD使用的是私有文件格式,这些文件只能在支持该格式的C…