直接结论:用 go.work,别用 replace 做本地联调。go.work 更稳定、路径变更不崩、ci 可控、ide 支持好;replace 仅为临时补丁,非协作方案;go build 报“module not in main module”因未在 go.work 根目录执行命令,且 use 路径须严格匹配相对路径、子模块需含 go.mod、import 路径须与 module 声明完全一致。

直接结论:用 go.work,别用 replace 做本地联调。 它更稳定、路径变更不崩、CI 可控、IDE 支持好。硬写 replace 是临时补丁,不是协作方案。
为什么 go build 会报 “module xxx is not in main module”
这不是依赖没写对,而是你没在正确上下文里执行命令。Go 工具链只认当前工作目录是否在 go.work 管辖范围内。
- 错误操作:
cd ./service-a && go build—— 此时 Go 只看service-a/go.mod,完全无视go.work - 正确操作:必须在含
go.work的根目录下执行go build ./cmd/app-main或go run ./cmd/app-main - 检查是否生效:运行
go list -m all | grep your-module-name,如果输出带(replaced)就说明还在走replace;正常应显示本地路径,无括号
go.work 文件里 use 路径写错的典型表现
路径错一个字符,模块就静默失效——不会报错,但代码里 import 成功、运行时 panic 找不到符号。
- 必须是相对
go.work所在目录的路径,不能以../开头,也不能用绝对路径 - 路径末尾不加
/,比如use ./pkg/util对,use ./pkg/util/错 - 子模块目录下必须存在
go.mod,否则go work use会成功但后续构建失败(Go 不报错,只跳过) - 多个模块同名?比如都叫
example.com/myproj/pkg/util,Go 会加载第一个匹配的——靠use顺序控制优先级
本地联调时模块间 import 路径怎么写才不出错
import 路径和 go.mod 里声明的模块路径必须严格一致,不是文件系统路径。
- 假设
pkg/util/go.mod内容是module example.com/myproj/pkg/util,那其他模块就得写import "example.com/myproj/pkg/util" - 不要用
./pkg/util或../pkg/util这类相对路径 import —— Go 不支持 - 模块路径中不能含
..、空格、大写字母开头(虽然语法允许,但某些工具链会拒接) - 改了模块路径?必须同步更新所有引用它的
go.mod中的require行(开发期可删掉,靠go.work自动解析)
真正容易被忽略的是:工作区模式下,go test 默认不自动包含所有模块的测试文件。想跑跨模块集成测试,得显式指定路径,比如 go test ./... -race,且确保每个子模块的 go.mod 里没残留旧 replace —— 它们会覆盖 go.work 的行为。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











