Files
cs-note/hzh/GolangStar/Go语言基础/Go语言依赖管理.md
T

158 lines
4.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
tags: [go, golang, go基础语法, modules, go modules, 依赖管理]
create time: 2026-06-07 15:00
---
# Go 语言依赖管理
## 概述
Go Modules 是 Go 1.11+ 引入的官方依赖管理方案。本文讲解 go.mod/go.sum 的核心结构、常用命令和关键环境变量的配置。
## 正文
### 为什么 Go 需要 Modules?
在 Modules 出现之前,Go 依赖 `GOPATH` 管理——所有代码必须放在 `$GOPATH/src` 下。这导致:
- 项目路径与代码仓库路径不一致
- 依赖版本无法锁定
- 多项目间依赖冲突
Go Modules 让每个项目**自包含**其依赖信息,不再依赖 GOPATH。
### 核心环境变量
| 变量 | 用途 | 推荐值 |
|------|------|--------|
| `GO111MODULE` | 开关(auto/on/off) | `on`(Go 1.14+ 默认) |
| `GOPROXY` | 模块代理地址 | `https://goproxy.cn,direct`(国内) |
| `GOSUMDB` | 校验数据库 | `sum.golang.org`(默认) |
| `GOPRIVATE` | 私有仓库域名 | 按需设置 |
```bash
# 国内开发者推荐配置
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct
```
> [!info] ℹ️ `direct` 的含义
> `GOPROXY=https://goproxy.cn,direct` 表示先从 goproxy.cn 拉取,如果返回 404/410,则回源到原始仓库(如 GitHub)。
### GOPRIVATE:私有仓库
对于不在公共代理中的私有仓库:
```bash
go env -w GOPRIVATE="github.com/myorg/*,git.internal.company.com"
```
> [!tip] 💡 通配符支持
> `github.com/myorg/*` 会匹配 `myorg` 下的所有子仓库。
### go.mod 文件结构
```go
module example.com/myproject // 模块路径(import 的基础路径)
go 1.21 // 所需最低 Go 版本
require ( // 直接依赖
github.com/gin-gonic/gin v1.9.1
gorm.io/gorm v1.25.5
)
require ( // 间接依赖(自动传递)
github.com/gin-contrib/sse v0.1.0 // indirect
)
replace ( // 替换某个依赖
golang.org/x/image => github.com/golang/image v0.18.0
)
retract v0.2.0 // 撤回不推荐的版本
```
> [!note] 📝 关键字段说明
| 字段 | 作用 |
|------|------|
| `module` | 当前模块的唯一路径,import 语句以此为前缀 |
| `go` | 声明兼容的 Go 最低版本 |
| `require` | 依赖列表,分直接和间接两类 |
| `replace` | 将 A 替换为 B(可用于本地开发或镜像) |
| `exclude` | 排除某个特定版本(Go 1.16+) |
| `retract` | 声明某版本不应被使用(Go 1.16+) |
### indirect 标记
当你的项目依赖 A,A 又依赖 B,但 A 的 go.mod 缺少 B 时,你的项目中 B 会被标记为 `// indirect`。
执行 `go mod tidy` 后,无用的 indirect 依赖会被移除。
### +incompatible 标记
语义化版本要求:v2+ 的模块路径需包含 `/v2`。如果作者忘了改路径,版本号后面会加上 `+incompatible`:
```go
require github.com/pkg/errors v0.9.1+incompatible
```
功能上与普通版本无异,只是提醒开发者这个模块没有遵循语义化版本规范。
### go.sum:安全校验
`go.sum` 记录每个依赖的哈希值,确保下载的内容未被篡改:
```
github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA=
github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqk=
```
> [!warning] ⚠️ 不要手动编辑 go.sum
> 它由 Go 工具链自动生成和维护。
### 常用命令速查
| 命令 | 作用 |
|------|------|
| `go mod init module/path` | 初始化新模块 |
| `go get package@version` | 添加/更新依赖 |
| `go mod tidy` | 清理无用依赖,补充缺失依赖 |
| `go mod download` | 下载依赖到本地缓存 |
| `go mod graph` | 打印依赖图 |
| `go mod vendor` | 导出依赖到 vendor/ 目录 |
| `go mod verify` | 校验依赖完整性 |
| `go clean -modcache` | 清除模块缓存 |
> [!tip] 💡 日常开发工作流
> ```bash
> go get github.com/example/pkg@latest # 添加/升级依赖
> go mod tidy # 清理
> go build # 编译(自动检查一致性)
> ```
### 版本选择规则
| 情况 | 行为 |
|------|------|
| 有语义化标签(v1.2.3) | 取最大主版本标签 |
| 无标签 | 取 main 分支最新 commit,生成伪版本号 |
| 伪版本号 | `v0.0.0-yyyyMMddHHmmss-abcdef123456` |
### replace 的使用场景
当公共代理不可用时,用 replace 指向镜像或本地路径:
```go
replace golang.org/x/image => github.com/golang/image v0.18.0
```
或者指向本地开发路径:
```go
replace mycompany/internal/pkg => ../internal/pkg
```
> [!info] ℹ️ replace 不影响 import 语句
> 代码中仍然写 `import "golang.org/x/image"`,Go 会自动识别 replace 映射到实际路径。