工作区模式与多模块
本教程共 80 篇 · 第 70 篇 · 更新于 2026-07-27 · 约 7 分钟阅读
70. 工作区模式与多模块
本节目标:学会用
go.work创建工作区,同时开发多个本地模块,理解它和replace的区别。
多模块开发的痛点
假设你有两个模块:example.com/hello(主程序)和 example.com/lib(库)。hello 依赖 lib,你在同时改两个。
老办法是用 replace 把 lib 指向本地路径:
// hello/go.mod
replace example.com/lib => ../lib
问题:replace 是写在 go.mod 里的,提交代码时得记得删掉,否则别人拉下来找不到本地路径。
工作区模式(Go 1.18 引入)解决了这个问题。
go.work 文件
工作区用 go.work 文件管理。创建:
mkdir workspace
cd workspace
go work init ./hello ./lib
生成 go.work:
go 1.26.0
use (
./hello
./lib
)
use 块列出工作区包含的模块。在工作区目录下跑 go build/go run/go test,Go 会同时把这些本地模块纳入解析。
实际演示
目录结构:
workspace/
├── go.work
├── hello/
│ ├── go.mod (module example.com/hello)
│ └── main.go (import example.com/lib)
└── lib/
├── go.mod (module example.com/lib)
└── lib.go
hello 的 go.mod 里正常写依赖:
require example.com/lib v0.0.0
不需要 replace。因为在工作区里,Go 发现 example.com/lib 有本地副本(./lib),就用本地的,不去远程下载。
cd workspace
go run ./hello # 用本地 lib 的代码跑 hello
改了 lib 的代码,hello 立刻能用到,不用重新 go get。
go work 命令
go work init ./mod1 ./mod2 # 创建工作区
go work use ./mod3 # 添加模块
go work use -r . # 递归添加子目录里的模块
go work edit -dropuse ./mod1 # 移除模块
go work sync # 同步依赖到各模块 go.mod
和 replace 的区别
| 特性 | replace | go.work |
|---|---|---|
| 写在哪 | go.mod(提交) | go.work(不提交) |
| 影响别人 | 是 | 否 |
| 管理多个模块 | 麻烦 | 专门为此设计 |
| 版本控制 | 要手动删 | gitignore 即可 |
Tip
go.work默认不提交。在.gitignore里加上go.work。这样你本地多模块联调,别人拉代码不受影响。
go.work 的优先级
工作区模式下,go.work 的 use 模块优先于 go.mod 的远程依赖。也就是说:
- 本地有的模块用本地代码
- 本地没有的模块正常从远程拉
这让工作区很适合「大部分依赖用远程版本,只对正在开发的几个模块用本地」的场景。
跨模块开发流程
- 在父目录建工作区:
go work init ./app ./lib1 ./lib2 - 正常开发,改任意模块的代码
- 在工作区根目录跑测试:
go test ./... - 想发布某个模块时,进到那个模块单独
go mod tidy
Note
go.work只影响本地开发。发布模块时,go.mod 里的依赖版本才是最终生效的。确保发布前 go.mod 的版本号是对的。
不需要工作区的情况
如果你只有一个模块,或者依赖都是远程的稳定版本,不需要工作区。工作区是为「同时改多个本地模块」准备的。
小结
go work init创建go.work,use块列出本地模块- 工作区里本地模块优先于远程依赖,改完立即可见
go.work不提交,加到.gitignore- 比
replace更干净,不影响别人 - 只在同时开发多个模块时才需要
下一节讲 GOPROXY 配置和发布模块。