go build 找不到包的根本原因是 go111module 环境变量未设为 on,导致 go 强制回退到 gopath 模式;即使有 go.mod 也会被忽略,必须确保 go111module=on、项目根目录含 go.mod 且不在 $gopath/src 下。

go build 为什么找不到包?先看 GO111MODULE 状态
Go 工具链是否走模块路径,不取决于你有没有 go.mod 文件,而取决于 GO111MODULE 环境变量的值。它有三个取值:on、off、auto(Go 1.13+ 默认)。
当设为 off 时,哪怕当前目录有 go.mod,go build 也会忽略它,强行回退到 GOPATH 模式——此时项目必须放在 $GOPATH/src 下,且 import 路径必须匹配远程仓库结构(如 github.com/user/repo)。
常见错误现象:go: cannot find main module 或 no required module provides package,往往就是 GO111MODULE=off 导致的“假性模块缺失”。
- 检查方式:
go env GO111MODULE - 临时关闭模块:
go env -w GO111MODULE=off - 恢复模块模式:
go env -w GO111MODULE=on,再运行go mod init example.com/myapp - 注意:
auto模式下,只有当前目录或其父目录存在go.mod时才启用模块;否则仍按 GOPATH 查找
项目放哪?GOPATH 不再是强制约束
在模块模式下,$GOPATH 只管三件事:存放老式非模块包($GOPATH/src)、缓存模块下载($GOMODCACHE,默认在 $GOPATH/pkg/mod)、生成可执行文件($GOPATH/bin)。你的项目代码可以放在任意路径——桌面、/tmp、U 盘,只要根目录有 go.mod,go run main.go 就能跑通。
但如果你把项目误放到 $GOPATH/src/example.com/foo 且没 go.mod,Go 会自动启用 GOPATH 模式,导致 replace 指令失效、vendor 被忽略、版本控制丢失。
Go 配置库,使用 spf13/viper — 分层优先级(flag > env >file > KV > default),提供 BindPFlag/BindPFlags、SetEnvPrefix + SetEnvKeyReplace 等功能。
- 模块项目路径自由,但 import 路径不再需要模拟 GitHub 结构;你可以写
import "myproject/utils",只要go.mod里定义了 module 名 -
go env GOPATH输出多个路径(用:或;分隔)时,只有第一个生效;其余被完全忽略 - 不要手动设置
GOROOT,除非你同时装了多个 Go 版本;出问题优先查PATH是否包含go二进制
依赖怎么存?pkg/mod 和 src 是两套系统
模块模式下,go get github.com/gorilla/mux 下载的包不会进 $GOPATH/src,而是解压到 $GOMODCACHE/github.com/gorilla/mux@v1.8.0(哈希校验后路径),并软链接到构建缓存。而 go get github.com/old/project(无 go.mod)才会落到 $GOPATH/src/github.com/old/project。
这意味着:同一依赖不同版本可共存(v1.7.0 和 v1.8.0 各自独立目录),go.sum 记录精确哈希,go mod vendor 可导出锁定版本的副本——这些在 GOPATH 模式下全不存在。
-
go list -m all查看当前模块所有直接/间接依赖及其版本 -
go mod graph | grep mux快速定位某依赖被谁引入 - 删除
$GOMODCACHE不影响项目运行(下次go build会重下),但删$GOPATH/src可能破坏老项目 - VS Code 的 Go 插件至今不支持单工作区多
go.mod(2026 年仍需开多个窗口)
vendor 目录在模块时代还值得用吗?
模块模式下 vendor 是可选行为,启用需加 -mod=vendor 参数(如 go build -mod=vendor),否则工具链默认忽略它。它的作用只剩一个:离线构建或 CI 环境中规避代理失败。
但要注意:go mod vendor 会把所有依赖(含 transitive)复制进 vendor/,体积膨胀快;且一旦启用 -mod=vendor,go get 将拒绝更新依赖——你得手动 go mod vendor 再提交。
- 新项目不建议默认开启 vendor;CI 中可用
go mod download预热缓存替代 - 如果用了 vendor,务必把
vendor/modules.txt提交进 Git,它是 vendor 的元数据快照 - GOPATH 模式下的 vendor 机制要求项目必须在
$GOPATH/src下;模块模式下无此限制
go.mod 就退回“干净”的 GOPATH,实际上环境变量、目录位置、甚至当前路径的父级是否存在 go.mod,都在暗中影响行为。golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










