go work 不能替代 go mod,仅负责多模块本地协同开发;go.work 必须置于所有模块共同父目录下,路径需以 ./ 开头且不支持嵌套,use 后需验证 go list -m all 输出是否含 => 符号。

go work 不能替代 go mod,它只负责让多个已存在的模块在本地开发时“互相看见”——不改 go.mod、不发版本、不拉远程包。
go.work 文件必须放在所有模块的共同父目录下
工作区根目录不是随便选的。如果你把 go.work 放在 ./api 里,那 ./core 就永远进不来;如果放在家目录或空文件夹,go 命令压根不会识别它。
- 正确做法:新建一个空目录(比如
myproject),把./api、./core、./cli全部作为子目录放进去,再在myproject/下执行go work init -
go.work不支持嵌套:子模块里再放一个go.work,go会直接报错go: cannot use work file because a nested work file exists - 路径必须平级:不能让
./core在上层目录(如../shared/core),go.work中的use和replace都只接受以./开头的相对路径
go work use 后 go run 还找不到本地模块?检查三件事
最常见的情况是:你执行了 go work use ./api ./core,但 go run ./api 仍去 GOPROXY 拉远程版,甚至报 cannot find module。
- 确认当前执行命令的目录就是
go.work所在目录——go不会向上递归找go.work,也不认子目录下的文件 - 运行
go list -m all,输出里必须出现类似example.com/core v0.0.0-00010101000000-000000000000 => ./core才算生效;如果只显示版本号没箭头,说明没走 workspace 模式 - 检查
GOFLAGS是否设了-mod=readonly,它会阻止go自动更新go.mod,导致依赖解析卡住;临时清掉它:GOFLAGS="" go run ./api
replace 是补丁,不是常规操作
go work use 已经声明“这些模块我本地正在开发”,绝大多数情况不需要 replace。只有当某个模块的 go.mod 里还硬编码着旧版本或远程路径时,才需要它兜底。
初始化并管理阿里云SDK Go 客户端,涵盖 sync.Once 单例、goroutine 安全、endpoint 与 region 配置、VPC 端点及调试。
立即学习“go语言免费学习笔记(深入)”;
- 场景一:模块 A 的
go.mod里有require example.com/b v0.1.0,但你本地改的是./b→ 在go.work里加replace example.com/b => ./b - 场景二:模块 A 的
go.mod里根本没requireB,只是代码里写了import "example.com/b"→ 只需go work use ./b,不用replace - 注意:
go.work中的replace优先级高于模块自身的replace,且全局生效,会影响所有被use的模块
CI/CD 和 IDE 需要特殊处理
workspace 是纯本地开发机制,上线构建和部分工具链并不默认支持它。
- CI 脚本里别假设
go.work存在:应退回到单模块模式,用go build -mod=mod或go mod vendor显式控制依赖来源 - VS Code 不会自动重载
go.work变更:加了新模块或改了replace,必须手动触发 “Go: Reload Window” 或点击状态栏的 “Go (Workspace)” 提示 - 不要在子模块目录里单独执行
go run main.go—— 它完全无视go.work;要么回根目录跑go run ./api,要么显式指定go run -workfile ../go.work ./main.go
真正容易被忽略的是循环依赖:A require B,B require A,go build 会卡住或报 import cycle not allowed,但错误信息里从不提 go.work。这时候得临时删掉 go.work,改用 replace 绑定,才能快速定位是不是 workspace 引入的隐式引用。

















