> 技术文档 > Go1.25 新特性:Go modules 终于要支持 Git 子目录,太感人了!!!

Go1.25 新特性:Go modules 终于要支持 Git 子目录,太感人了!!!

大家好,我是煎鱼。

在过去 Go 最早是使用 GOPATH 的模块依赖管理方式,源于 Go 的大单体仓库的模式。随后 @rsc 推行了 Go modules(也就是现在的 go.mod)的模块依赖管理方式。

但 Go modules 本身也依然有不少的问题点,其中一个是类似 GitLab subgroups 的兼容适配问题。

与我们今天分享的问题点也比较相近。

业务背景

原提案作者 @Anmol Sethi 有一个开源项目 nhooyr/websocket[1]

Go1.25 新特性:Go modules 终于要支持 Git 子目录,太感人了!!!

该项目的仓库根目录塞满了 Go 文件,造成页面混乱、不容易阅读。(作者自述)

于是作者想要将模块源码迁移到仓库下的子模块,这样可以实现根目录就干净了,文档和配置文件也不会和源码混在一起,更利于维护与阅读。

但是很无奈的是,Go 并不支持模块在仓库子目录中的情况,导致如果尝试:

go get github.com/nhooyr/websocket/mod@latest

或在 go.mod 中这样引用:

require github.com/nhooyr/websocket/mod v0.1.0

就会失败,因为 go module 无法识别子模块的场景。这是该作者遇到的真实案例。

不支持的原因

在 Go 的模块代理机制中,cmd/go 会根据代码里对应的 go-import meta 标签来定位模块的位置。

例如下面这个最常见的 group/project 例子,我们模仿 go get 命令直接拉取:

curl -X GET \"https://gitlab.xxx.com/libraries/example?go-get=1\"

现有的 cmd/go 机制只会把仓库根目录当作模块根。

如果在 Git 仓库中,实际把 go 模块源码放在子目录(例如:github.com/eddycjy/repo/subdir),则 cmd/go 无法正确处理。

Go1.25 新特性:Go 模块将支持 Git 子目录

@Anmol Sethi 发起了新提案《cmd/go: allow serving module under the subdirectory of git repository[2]》:

Go1.25 新特性:Go modules 终于要支持 Git 子目录,太感人了!!!

期望去推动并解决这个问题。

最终定论是,允许在 go-import meta 标签中明确支持指定子目录,例如:

这样 Go 命令就可以把模块定位在包含源码的子目录中,而不是整个仓库根目录。

核心变更上主要是对 cmd/go 的解析逻辑进行了扩展,支持新 meta 标签格式 root-path vcs repo-url subdir 的解析:

Go1.25 新特性:Go modules 终于要支持 Git 子目录,太感人了!!!

以此达到了 go-import 元标记中指定子目录的功能。

对 Go 官方这部分具体代码感兴趣的同学,可以查看以下 CL《cmd/go: add subdirectory support to go-import meta tag[3]》:

Go1.25 新特性:Go modules 终于要支持 Git 子目录,太感人了!!!

总结

这个提案目前已经通过并且合并,预计将会在 Go1.25 中开始正式应用。也是广大 Go 开发者的好消息了。

Go1.25 新特性:Go modules 终于要支持 Git 子目录,太感人了!!!

而且普遍从 issues 来看,大家都认为这将是一个比较实用的改进,特别适合 monorepo 维护与多语言项目结构。

推荐阅读

  • Go 模块使用 GitLab subgroups 的问题

  • Go 错误处理的争论,终于有了结论!!

  • Go1.25 新特性:支持 FlightRecorder 模式、支持读取符号链接、OS 版本推进等

参考资料

[1] 

nhooyr/websocket: https://github.com/coder/websocket

[2] 

cmd/go: allow serving module under the subdirectory of git repository: https://github.com/golang/go/issues/34055

[3] 

cmd/go: add subdirectory support to go-import meta tag: https://github.com/benjivesterby/go/commit/835e36fc7f631f74233edfd4ab43b6b56833db86

关注和加煎鱼微信,

一手消息和知识,拉你进技术交流群👇

Go1.25 新特性:Go modules 终于要支持 Git 子目录,太感人了!!!

你好,我是煎鱼,出版过 Go 畅销书《Go 语言编程之旅》,再到获得 GOP(Go 领域最有观点专家)荣誉,点击蓝字查看我的出书之路

日常分享高质量文章,输出 Go 面试、工作经验、架构设计,加微信拉读者交流群,和大家交流!

原创不易 点赞支持