go mod download 在子目录不工作,因它仅在含 go.mod 的模块根目录生效;若在子目录执行,会报错或静默失败,必须进入各模块根目录单独运行,或多模块项目需用 find 命令批量处理。

go mod download 为什么在子目录里不工作
因为 go mod download 默认只在模块根目录(即包含 go.mod 的目录)下生效。如果你在多层子目录(比如 cmd/myapp/ 或 internal/service/)里执行,Go 会尝试向上查找最近的 go.mod,但若当前工作目录不在模块根路径下,且没显式指定模块路径,它可能报错 no Go files in current directory 或静默失败——实际什么都没下载。
常见错误现象:go mod download 执行后 vendor/ 空空如也,或者 go build 时仍提示 missing module。
- 必须在模块根目录(含
go.mod的顶层目录)运行go mod download - 如果项目有多个
go.mod(比如 monorepo 中多个子模块),每个子模块需单独进入其根目录执行 - 不能靠
cd .. && go mod download这种模糊路径跳转——得确认当前pwd确实是模块根
如何批量处理嵌套多模块项目的依赖下载
当一个仓库里有多个独立模块(例如 api/、worker/、pkg/core/ 各自带 go.mod),go mod download 不会自动递归扫描。你得手动定位并逐个执行,或写一行 shell 命令快速覆盖。
推荐做法:用 find 找出所有 go.mod,再对每个目录执行下载:
find . -name go.mod -exec dirname {} \; | while read dir; do echo "→ $dir"; cd "$dir" && go mod download; cd - >/dev/null; done注意点:
-
go mod download本身不读取子目录下的go.mod,所以不能只在顶层跑一次 - 某些 CI 场景下建议加
-x参数看详细命令:go mod download -x,方便排查网络或 proxy 问题 - 如果用了
GO111MODULE=off或 GOPATH 模式,go mod download直接失效——确保环境变量为GO111MODULE=on
vendor 目录没更新?检查 go mod vendor 的作用域和缓存
go mod vendor 和 go mod download 是两件事:前者把依赖复制进 vendor/,后者只是下载到本地缓存($GOPATH/pkg/mod)。很多人以为下载完 vendor 就自动同步了,其实不会。
正确流程是:先 go mod download(确保依赖已拉取),再 go mod vendor(生成 vendor)。但在多层目录下容易漏掉这一步,或在错误目录执行导致 vendor/ 内容不全。
-
go mod vendor必须在模块根目录运行,否则会报no modules to vendor - 如果模块用了
replace或exclude,go mod vendor仍会按go.mod解析结果打包,但不会 vendor 被 exclude 的模块 - 想跳过 vendor 中的测试文件?加
-v参数:go mod vendor -v,但注意这会增加体积,不是默认行为
proxy 和 private repo 配置在多模块下容易失效
Go 的代理配置(GOPROXY)和私有仓库认证(.netrc 或 git config)是全局或用户级的,但多模块项目中,不同子模块可能依赖不同私有源。这时单靠 GOPROXY 不够,得配合 go env -w GONOPROXY=*.example.com 或在每个模块的 go.mod 里写 replace。
典型坑:
- 某个子模块依赖公司内网 GitLab,但
GOPROXY没配GONOPROXY,导致go mod download卡住或 403 -
git config --global url."ssh://git@company.com".insteadOf "https://company.com"在 CI 容器里没生效,因为容器没挂载 SSH key 或没设 git config - 使用
go mod edit -replace临时替换依赖时,只影响当前模块的go.mod,其他子模块不受影响——得逐个处理
复杂点在于:模块边界由 go.mod 定义,而 Go 工具链不会跨模块自动继承 proxy 或 auth 配置。每个模块都是独立的依赖解析单元,哪怕它们物理上挨着。

















