go 1.13起默认启用go module,go build找不到包是因为项目进入模块模式后不再读取gopath下的包;必须在项目根目录执行go mod init生成go.mod,并用go mod tidy补全依赖和更新go.sum。

Go 1.13 起已默认启用 Go Module,所有新项目必须用 go mod,旧的 GOPATH 和 vendor 方式无法再可靠复现构建结果。
为什么 go build 突然找不到包了?
常见现象:把老项目从 $GOPATH/src 直接挪到任意路径后执行 go build 报错 cannot find package。这不是路径问题,而是 Go 已自动进入模块模式,不再读取 GOPATH 下的包。
- 只要项目根目录有
go.mod文件,或当前不在$GOPATH/src且无go.mod(GO111MODULE=auto时),Go 就强制走模块逻辑 -
vendor/目录不会被自动启用——必须显式加-mod=vendor参数:go build -mod=vendor - 若想临时退回到 GOPATH 模式,需设
GO111MODULE=off,但仅限极少数遗留 CI 场景,不推荐长期使用
go mod init 后依赖没自动拉取,怎么办?
go mod init 只生成空的 go.mod,它不分析代码、不下载任何依赖。真正触发依赖发现的是首次 go build 或 go list 等命令。
- 运行
go build后,Go 会扫描所有.go文件里的import,自动补全require到go.mod,并下载对应版本 - 如果 import 路径和你期望的模块路径不一致(比如旧代码 import "mylib",但实际模块是
github.com/user/mylib),go build会失败;此时需先修正 import 路径,或用replace临时映射 - 别手动编辑
go.mod添加 require 后就以为完事了——必须跟一句go mod tidy,否则go.sum不更新,CI 构建可能校验失败
如何让旧 vendor 项目逐步迁移到 Go Module?
直接删掉 vendor/ 并跑 go mod init 往往失败,因为旧 vendor 里可能混着 fork 修改、无 tag 版本、甚至 patch 过的包。
- 先保留
vendor/,运行go mod init初始化模块,再执行go mod vendor——这会把当前go.mod中声明的依赖重新 dump 到vendor/,覆盖原有内容 - 对比新旧
vendor/差异,重点关注被删掉的包:它们大概率是间接依赖或未被 import 的冗余项,可安全移除 - 若某依赖在
vendor/里有本地 patch,不要删,改用replace指向本地路径:replace github.com/xxx/lib => ./vendor/github.com/xxx/lib - 迁移完成后,删掉
vendor/,靠go.mod+go.sum管理,提交时只留这两个文件
go.sum 频繁变动,是不是有问题?
不是 bug,是正常行为。每次从不同代理源下载、或远程模块 tag 被重写,都会导致哈希值变化,go.sum 必须更新以保证完整性校验有效。
-
go.sum每行格式为module@version h1:xxx和module@version/go.mod h1:xxx,后者校验的是该模块自身go.mod文件的哈希 - 如果团队多人提交时
go.sum冲突频繁,检查是否用了不同GOPROXY(比如有人直连,有人用私有代理)——统一配置export GOPROXY=https://proxy.golang.org,direct - 严禁手动删
go.sum行或整个文件;出问题时用go mod download重拉一遍即可
真正的难点不在命令怎么敲,而在理解 go.mod 是声明,go.sum 是证据,go build 是验证动作——三者缺一不可。任何跳过其中一环的“平滑过渡”,最后都会卡在 CI 构建或生产部署上。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











