go111module=on 是唯一正确配置,否则 ci 因 auto 模式 fallback 致依赖失控;goproxy 必须含 ,direct 以支持私有仓库;gobin 需显式设置并加入 path;gopath 在模块模式下仅影响 go install 输出路径。

GO111MODULE=auto 是最大隐患
很多项目本地能跑、CI 报错,根源就在这儿。GO111MODULE=auto 会根据当前目录有没有 go.mod 动态切换模式:有就走 module,没有就 fallback 到 GOPATH。但 CI 环境往往清空缓存、重拉代码,go.mod 可能还没生成,go get 就已执行——结果依赖全写进 $GOPATH/src,go.sum 不生成,版本完全失控。
正确做法只有一条:go env -w GO111MODULE=on。这比写 shell 配置更可靠,尤其在 Docker 构建或远程 runner 中生效稳定。
- 验证方式不是看
echo $GO111MODULE,而是运行go env GO111MODULE,输出必须是on - 如果项目已有
go.mod却仍报go: not in a module,说明环境变量被覆盖(比如 IDE 启动时没继承 shell 配置) - Go 1.16+ 默认开启 modules,但旧脚本或团队成员本地设了
off,会导致行为不一致
GOPROXY 缺少 ,direct 导致私有仓库 404
只配 GOPROXY=https://goproxy.cn 看似能加速,实则埋雷。所有模块——包括 git.internal.com/mylib 这类内网地址——都会被转发到代理,而代理无法访问你的私有 Git,最终返回 404 或 “no required module provides package”。
必须带 ,direct 回退:go env -w GOPROXY=https://goproxy.cn,direct。这样 Go 会先尝试代理,失败后自动走 direct(即直连 Git 地址)。
- 企业级配置还需加
GOPRIVATE:例如go env -w GOPRIVATE=git.internal.com,github.com/myorg,告诉 Go 这些域名跳过代理和校验 - 验证是否生效:删掉
go/pkg/mod/cache,运行go mod download,私有模块应秒级完成,而非卡在 “Fetching” - VS Code/Goland 双击启动时,环境变量常不继承 shell,需在 IDE 设置里显式覆盖
GOPROXY
GOBIN 不设或没进 PATH,go install 的二进制就找不着
go install ./cmd/foo 成功执行,但终端敲 foo 报 “command not found”,90% 是因为 GOBIN 没设,或设了但没加进 PATH。Go 不会自动把 GOBIN 加入路径,它只负责把二进制文件放进去。
Linux/macOS 推荐统一设为 $GOROOT/bin;Windows 设为 %GOROOT%\bin。别用 $HOME/go/bin——容易和 GOPATH 混淆,且 CI 中 GOPATH 可能为空。
-
GOBIN必须显式设置,不能留空;GOROOT也必须指向真实安装路径(如/usr/local/go),不能是软链接顶层 - 设置后务必执行
export PATH=$PATH:$GOBIN(bash/zsh)或对应 Windows PATH 添加操作 - 验证不是
echo $GOBIN,而是which go(macOS/Linux)或where go(Windows),输出路径里必须含GOBIN值
GOPATH 在模块模式下只剩“垃圾桶”功能
只要 GO111MODULE=on 且项目有 go.mod,GOPATH 对依赖解析、构建、下载就彻底失效。它只剩两个作用:决定 go install 二进制的落盘位置($GOPATH/bin),以及保留 go get 在无模块时的老行为。
常见错误是:以为 $GOPATH/src/github.com/user/lib 下放了代码,go build 就能识别——模块模式下根本不会扫描那里,只认 go.mod 里的 require、replace 和本地相对路径。
- 如果改了
$GOPATH/src下的某个依赖却没配replace,module 模式完全无视你的修改 -
go list -m all显示的是实际解析出的模块版本,和GOPATH无关;报错cannot find module providing package通常是因为go.mod缺require或replace写错路径 -
GOPATH若保留,建议设为独立路径(如$HOME/go),不与项目目录混用,避免误操作污染
go env -w 写的是 Go 自己的配置,但 IDE、CI runner、Docker 容器未必读它;shell 配置文件(如 .zshrc)设的变量,图形界面启动的编辑器又常常加载不到。得在每个执行上下文里单独确认 go env 输出,而不是默认“设了就等于生效”。golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











