很好,这个问题涉及到 Go module 的真正工作机制,我们讲清楚三个点:
❌ 不必须。
Go 只要求:
它能通过 module 路径找到代码
这个路径可以是:
✅ 可以。
有三种方式。
假设你有:
/Users/edward/chat-service
/Users/edward/user-service
在 user-service/go.mod 里:
require github.com/edward/chat-service v0.0.0
replace github.com/edward/chat-service => ../chat-service
这样:
import "github.com/edward/chat-service/pkg/logger"
实际上会用:
../chat-service
本地代码。
不需要 GitHub,不需要发布版本。
更专业的方式:
在上级目录:
go work init
go work use ./chat-service
go work use ./user-service
生成:
go.work
这样多个 module 自动本地联动。
不需要 replace。
这是现在官方推荐方式。
公司内部:
git.company.com/common-lib
不需要公开在 GitHub。
这个非常重要。
假设你:
go get github.com/edward/chat-service
👉 会下载整个仓库源码。
包括:
internal/
pkg/
cmd/
全部都会下载。
但是:
Go 编译器限制:
你不能 import internal。
例如:
import "github.com/edward/chat-service/internal/xxx"
会报错:
use of internal package not allowed
| 行为 | internal |
|---|---|
| 下载源码 | ✅ 会 |
| 允许 import | ❌ 不允许 |
internal 是编译时访问控制,不是下载控制。
用:
go work
用:
git tag v1.0.0
然后:
go get company.com/common-lib@v1.0.0
只有当:
才需要 push + tag。
❌ 不必须
✅ 可以,用:
✅ 会下载
❌ 但不能 import
Go module 是:
代码分发机制
internal 是:
访问控制机制
它们不是一回事。
如果你愿意,我可以给你一份:
🔥 go work + 多模块本地开发完整示例结构图
这个在微服务时代非常重要。