go模块依赖管理倒逼项目拆分为可独立构建、有明确边界的模块;domain层须纯结构体与接口,不引入其他internal包;多服务共用时应提为独立模块而非replace;前端需置于web/等无go.mod目录并隔离构建。

Go 模块依赖管理本身不决定目录结构,但会倒逼你把项目拆成可独立构建、可复用、有明确边界的模块 —— 否则 go mod tidy 会报错、replace 会失效、go build 会找不到包。
多个服务共用一套 domain 层时,怎么避免循环依赖?
常见错误现象:go build 报错 import cycle not allowed,比如 cmd/api → internal/service → internal/repository → internal/model → 又试图 import internal/service。
- domain 层(如
internal/model、internal/domain)必须只含结构体、接口定义、纯业务逻辑函数,不 import 任何其他 internal 子目录 - repository 接口定义放在
internal/domain或internal/port,实现放在internal/repository;service 只依赖internal/domain,不碰internal/repository - 如果多个 cmd 都需要同一套 domain,就把
internal/domain提成独立模块(比如github.com/yourorg/domain),在各项目go.mod中require它,而不是用replace指向本地路径
前端 + 后端同仓库时,如何让 Go 模块不污染前端构建?
使用场景:一个 monorepo 里同时放 Vue/React 前端和 Go 后端,但 go mod 不该扫描前端代码,前端工具也不该误读 go.mod。
- 前端代码必须放在
web/、frontend/或ui/这类与 Go 模块无关的目录下,且该目录不能包含go.mod -
.gitignore里加/web/node_modules/、/web/dist/,但不要忽略/web/go.mod—— 如果你误建了,go mod就会把它当子模块处理 - CI 构建时,Go 部分只执行
cd cmd/api && go build,前端部分只执行cd web && npm install && npm run build,两者完全隔离
本地 replace 失效的三个典型原因
错误现象:go run cmd/api/main.go 仍拉远程版本,不走本地修改的子模块。
-
replace路径写错:必须是模块导入路径(如github.com/yourorg/user)→ 本地相对路径(如./modules/user),不能写成./user或../user - 子模块没自己的
go.mod:replace只对已声明为 module 的路径生效,go mod init github.com/yourorg/user缺一不可 - 父模块没运行
go mod tidy:replace声明后,必须执行一次go mod tidy才会把依赖解析结果写入go.sum并生效
真正难的不是怎么写 replace,而是判断什么时候该拆模块、什么时候该合并 —— 比如 internal/config 和 internal/logger 是否该独立成 pkg/config,取决于它们是否被外部项目复用过。没被复用过就别提前拆,否则只会增加 go mod 维护成本。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











