go work 是 Go 1.18 引入的多模块工作区管理机制,必须用于同一仓库中多个独立 go.mod 模块(如 api/、core/、cli/)需相互引用、统一构建或调试的场景,否则会因“module not in main module”报错。
当你在同一个代码仓库里维护多个 go.mod 模块(比如 api/、core/、cli/ 各自独立定义依赖),又想让它们彼此引用、统一构建或调试时,go work 就不是可选项,而是必需品。否则 go build 或 go test 会报错:cannot load xxx: module xxx is not in the main module。
它本质是顶层工作区(workspace)的描述文件 go.work,用来显式声明哪些子目录是 Go 模块,并让 go 命令把它们“拼”成一个逻辑整体。
别手动写 go.work —— 它结构简单但格式敏感,出错会导致整个 workspace 失效。始终用命令生成和更新:
go work init ./api ./core ./cli
go work use ./admin
go work use -r ./legacy
go work list
go.work 里不能写相对路径以外的路径(比如不能含 ../),也不能指向空目录或不含 go.mod 的目录;否则 go 命令会静默忽略该条目,但后续 go run 可能找不到包。
模块间 import 不再依赖 GOPATH 或目录深度,只认 module 声明的路径。例如:
api/go.mod 里写的是 module github.com/you/project/api
core/go.mod 里写的是 module github.com/you/project/core
api/main.go 中要导入 core,必须写:import "github.com/you/project/core",而不是
"../core" 或 "core"
这个路径必须和目标模块的 go.mod 第一行完全一致,包括大小写和斜杠结尾(不能多也不能少)。IDE(如 VS Code + gopls)通常能自动补全,但 CI 构建失败时,90% 是因为 import 路径和 go.mod 声明不匹配。

要提交,且必须进版本库。它不是开发环境临时文件,而是项目多模块拓扑的“源代码级声明”。CI 流水线(比如 GitHub Actions)需要它才能正确解析模块关系、执行 go test ./... 或 go build ./cmd/...。
但注意两点:
go.work 中的路径是相对于它自身位置的,所以它应该放在仓库根目录,且所有 use 路径都用 ./xxx 形式go.work 里用 replace 或 exclude —— 这些属于单模块控制逻辑,应写在对应 go.mod 里;go.work 只做模块发现,不干预依赖解析最容易被忽略的是:本地开发时 go.work 生效,但某些旧版 Go(GOWORK=off。