当前位置:首页 » 《休闲阅读》 » 正文

依赖管理(go mod)

4 人参与  2024年11月25日 14:01  分类 : 《休闲阅读》  评论

点击全文阅读


目录

一、GOPATH

二、Vendor

三、Go Module


Go的依赖管理主要经过了3个重要阶段

1、GOPATH

2、Vendor

3、Go Module

早期Go使用GOPATH进行依赖管理,但是GOPATH不方便管理多个版本。

后来增加了Vendor,允许把项目连同代码一起管理。

18年,Go1.11引入全新的依赖管理工具Go Module,直到Go1.14才走向成熟。

    从GOPATH到vendor,再到Go Module,这是一个不断演进的过程,了解每代依赖管理的痛点,能够更好的明白下一代依赖管理的初衷。

    故,我将会从GOPATH讲起,经过vendor最后到Go Module。

各版本依赖管理的时间分布            

依赖管理方法

引入版本

时间

状态

GOPATH

Go 1.0

2012 年(Go 1.0)

Go 的早期依赖管理方式,已逐步被 Go Module 取代,但仍在支持

Vendor

Go 1.5

2015 年

一种解决 GOPATH 依赖冲突的过渡方案,Go 1.6 起成为默认方案,但现在被 Go Module 取代

Go Module

Go 1.11

2018 年(实验)

Go 1.13 起成为默认依赖管理方式,是目前官方推荐的管理方案

一、GOPATH

    刚刚接触GO的新手,一般都对GOPATH感到困惑。通常由两方面造成的

    Go语言解决办法有两种:

将从前的卸了,再亲自安装一次听我下面的讲解 Ψ( ̄∀ ̄)Ψ

    建议选择第二种方法,既然来到了这里,就要相信我的讲解。本部分主要介绍GOPATH其密切相关的GOROOT,首先看一下GOROOT。

1. GOROOT是什么

定义:

    通常,我们说安装Go语言,实际上是安装Go的编译器与标准库,两者位于同一个安装包中。

    假如在Windows上,使用Installer安装Go,他们会被默认安装到C:\Go目录下。该目录即为GOROOT目录。

    里面包含了开发Go应用程序所需要的所有组件。如编译器、标准库和工具所在的位置。

    它是 Go 语言自带的环境变量,用户通常无需更改。

作用:

Go 编译器及工具链所在的目录。Go 的标准库代码(如 fmt、os 等)。

默认值:

    安装 Go 语言时,GOROOT 会自动配置为安装目录的路径。例如:

Windows 上:C:\GomacOS/Linux 上:/usr/local/go

是否需要手动设置:

    一般不需要手动设置 GOROOT,Go 安装程序会自动配置。如果需要自定义(比如安装多个 Go 版本),可以手动设置环境变量 GOROOT。

查看当前的 GOROOT:

go env GOROOT // 查看路径

2. GOPATH:工作区目录

定义:

GOPATH 是 Go 工作区目录,用于存放:

代码:所有项目的源码(src)。依赖包:第三方库的下载路径(pkg)。可执行文件:编译后的二进制文件(bin)。

作用:

Go 工具链在哪里查找和存储你的 Go 项目和依赖。go install 和 go build 命令,生成可执行文件或中间文件。

默认值:

    如果没有显式设置,Go 会将 GOPATH 默认设置为用户主目录下的 go 文件夹:

Windows 上:%USERPROFILE%\gomacOS/Linux 上:$HOME/go

目录结构:

一个典型的 GOPATH 目录结构如下:

GOPATH/├── bin/      # 存放可执行文件├── pkg/      # 存放已编译的依赖包└── src/      # 存放 Go 项目的源码

如何设置 GOPATH:

你可以手动设置 GOPATH 为自定义的目录(可多路径,但较少用)。例如:

# Linux/macOSexport GOPATH=/path/to/your/workspace# Windows(通过系统环境变量设置)set GOPATH=C:\path\to\your\workspace

查看当前的 GOPATH:

go env GOPATH

缺点:

    GOPATH的优点是简单,但是不能很好的适应实际项目的工程需求。比如有两个项目A和B,如果两个项目都引用第三方库T,只是版本不同。

使用,T v1.0使用,T v2.0

    由于编译器固定依赖GOPATH / src 下查找GOPATH / src / T 这条路径,又因为无法在同一个GOPATH目录下储存T的两个版本。所以A、B无法共享同一个GOPATH,需要各自维护一个,带来极大的不便。针对GOPATH的缺点,Go语言社区提供了Vendor机制。从此依赖管理进入了第二阶段。

GOROOT 与 GOPATH 的主要区别

区别

GOROOT

GOPATH

定义

Go 安装目录

Go 工作区,存放用户项目和依赖

包含内容

标准库、编译器、工具等

用户源码、依赖包缓存、可执行文件等

是否可修改

一般不需要修改,由 Go 自动设置

用户可以设置为任意路径

使用场景

Go 标准库查找、工具链使用

非模块化项目存储、编译生成文件

总结

 指向 Go 安装目录,包含标准库和工具,不建议修改。 指向工作区目录,存放用户项目和依赖,是用户项目的主要工作目录。

二、Vendor

    上部分,我们介绍了使用GOPATH的痛点:多个项目无法共享同一个GOPATH,虽然vendor仍然无法多个项目无法共享同一个GOPATH,但是它提供了一种机制,让项目的依赖隔离而不互相干扰。

    自 Go 1.6起,vendor机制正式启用,它允许把项目存放在vendor的目录中,可以把这个vendor目录,简单的理解成私有的GOPATH目录。项目编译时,编译器会优先从vendor目录中寻找依赖包,如果在vendor中找不到,才会去GOPATH中寻找。

    虽然vendor并未推出历史舞台,甚至在离线场合下更适用。

    但是Go Module已成为主流,如果读者们想得到vendor更详细的资料,可以上网另行查询。

三、Go Module

在Go 1.11中,Module的特性首次被引用,标志着Go的依赖进入第三个时代。

Go Module 基本上解决了 GOPATH 和 vendor 时代的遗留问题,看到这里的读者基本能了解:

GOPATH 时代,最大的困惑时无法让多个项目共享package的不同版本。

在vendor时代,可以通过将每个项目依赖的 package 放到 vendor 中可以解决,但是使用 vendor的问题是无法很好的管理依赖package,比如升级package。

而Go Module 更像一种全新的依赖管理方案。

Go Module基础

1、module的定义

    官方给 module 的定义是:A module is a collection of related Go packages that are versioned together as a single unit.

    定义非常清晰,一组 package 的集合一起被标记版本,即一个 module。

    通常而言,一个仓库包含一个 module(虽然也可以包含多个,但不推荐),所以仓库、module 和 package 的关系如下:

        ◎  一个仓库包含一个或多个 module。

        ◎  你每个module 包含一个或多个 package。

        ◎  每个 package 包含一个或多个源文件。

    另外,一个 module 的版本号规则必须遵循语义化规范,版本号必须使用v(major).(minor).(patch)格式,比如v0.1.0、v1.2.3等。

    下方给出了,语义化版本的规范。

语义化版本的规范

    语义化版本 (Semantic Versioning) 已成为事实上的标准,几乎知名的开源项目都遵循该规范,更详细的信息请前往 semver官网査看,在此只提炼一些要点,以便于后续的阅读。

    版本格式 v(major).(minorr).(patch)中的 major 指的是大版本,minor 指的是小版本,patch 指的是补丁版本。

        ◎ major: 当发生不兼容的改动时才可以增加该版本,比如 v2.x.y与 v1.x.y是不兼容的。

        ◎ minor: 当有新增特性时才可以增加该版本,比如 v1.17.0 是在 v1.16.0的基础上增加了新的特性,同时兼容 v1.16.0。

        ◎ patch: 当有 Bug修复时才可以增加该版本,比如 v1.17.1修复了 v1.17.0 上的 Bug,没有增加新特性。

    语义化版本规范的好处是,用户通过版本号就能了解版本信息。

2、快速实战

    纸上得来终觉浅,觉知此事要躬行,后续我会在补充一下实战,让大家对Go Module认识的更加清楚。

讲到这里了,大家肯定对 go mod 与 Go Module 之间的差异有些许疑惑,接下来我来细细讲解。

Go Module 与 go mod 的区别

区别

Go module

go mod 命令

定义

Go 的模块化系统,用于管理依赖和版本

Go 工具链中的子命令,用于操作和管理 Go module

作用

使得 Go 项目支持依赖版本管理、减少冲突

具体操作模块的工具,包含初始化、下载、清理等子命令

使用方式

自动在项目根目录生成

go.mod

 文件,记录模块的依赖信息

使用如

go mod init

 等命令管理模块依赖

依赖管理

管理项目的依赖关系和版本控制

提供修改

go.mod

 文件的命令,以方便操作模块

举例

在项目的根目录下:

# 初始化一个 Go module,会在当前目录生成 go.mod 文件go mod init my_project# 整理依赖,自动移除未使用的依赖包go mod tidy# 下载所有依赖go mod download

总体来说:

module 是 的模块化系统的概念,它定义了依赖管理的机制。mod 是管理 Go module 的命令集合,用于具体执行对模块的各种操作。

3、go.mod 与 指令

在 Go 中,go.mod 文件go mod 命令行工具提供了依赖管理的核心功能。以下是详细说明。

1. go.mod 文件

go.mod 是 Go 项目的模块文件,用于定义模块名、依赖项和版本等信息。一个典型的 go.mod 文件示例如下:

module example.com/myappgo 1.20require (    github.com/gin-gonic/gin v1.8.1    golang.org/x/crypto v0.5.0)replace golang.org/x/crypto v0.5.0 => ./local/crypto
module:定义当前项目的模块路径,一般为代码仓库路径。go:指定所使用的 Go 版本(这里是 1.20)。require:列出当前模块所依赖的其他模块及其版本。replace:用于指定模块的替代版本或本地替代路径,通常在开发调试阶段使用。

go.mod 文件自动生成

    可以通过在项目目录运行 go mod init <module_name> 来自动生成 go.mod 文件。例如,go mod init example.com/myapp。

2. go mod 命令行管理

go mod 命令行工具用于管理模块的依赖项和版本控制,以下是常用的命令:

2.1 go mod init <module_name>

初始化当前项目的模块系统,生成 go.mod 文件:

go mod init example.com/myapp

2.2 go mod tidy

清理依赖,移除不再使用的包并添加遗漏的包。

go mod tidy
go mod tidy 会检查 go.mod 和 go.sum 文件,移除未引用的模块,并确保所有依赖项存在于 go.sum 文件中。

2.3 go mod download

下载依赖包到本地的模块缓存中,但不会修改 go.mod 文件。

go mod download

2.4 go mod vendor

将所有依赖的包下载到项目的 vendor 目录中。

go mod vendor
Go 1.14 引入的 vendor 模式在构建项目时优先从 vendor 目录中查找依赖项,可以用来解决部署环境中网络不通畅的问题。

2.5 go mod graph

展示依赖模块之间的关系图,帮助理解依赖结构。

go mod graph

2.6 go mod verify

验证依赖的包文件是否正确,检查 go.sum 文件中保存的哈希值是否匹配下载的模块。

go mod verify

讲到这里也接近了尾声,创作本篇博客倾尽了全力,虽不免仍有些片面。但从基础上看,带领大家,重新认识了一遍依赖管理,并从GOPATH讲起,经过vendor最后到Go Module,还是不错的。

希望大家有收获,期待下次再见。


点击全文阅读


本文链接:http://m.zhangshiyu.com/post/191783.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1