Web Analytics

Go Monorepo 实战:用 Vanity URL 管理多模块

Monorepo 的困境 你的团队在使用 monorepo。所有 Go 服务都放在一个 Git 仓库里: monorepo/ ├── go/ │ ├── auth/ │ │ └── go.mod # module github.com/org/monorepo/go/auth │ ├── config/ │ │ └── go.mod # module github.com/org/monorepo/go/config │ └── logger/ │ └── go.mod # module github.com/org/monorepo/go/logger ├── proto/ ├── deploy/ └── README.md 三个 Go 模块,一个仓库。这是常见的模式——共享 CI、原子化的跨模块修改、一致的版本管理。 但 import path 又长又丑,还嵌套得很深: import ( "github.com/org/monorepo/go/auth" "github.com/org/monorepo/go/config" "github.com/org/monorepo/go/logger" ) 而且绑定在 GitHub 上。要迁移到 GitLab?所有 import 都得改。 你想要 vanity URL: import ( "go.company.com/auth" "go.company.com/config" "go.company.com/logger" ) 但问题来了:传统的 go-import meta 标签是一个 import path 映射一个 repo。你的 monorepo 是一个 repo 里有三个模块。怎么搞? ...

2026年7月13日 · Tony Bai

30 秒为你的 Go 模块设置自定义导入路径

什么是 Vanity URL? 简单来说,Vanity URL 让你的 Go 模块拥有一个属于你自己的导入路径,而不是绑定在 GitHub/GitLab 的地址上。 // ❌ 冗长且绑定平台 import "github.com/your-org/your-project" // ✅ 简洁、品牌化、与平台无关 import "go.yourcompany.com/your-project" 底层代码可以放在任何 Git 服务器上——GitHub、GitLab、Gitea、自建服务器都行。更换代码仓库时,import path 不需要任何改动。 这篇教程带你从零开始,30 秒搞定。 Step 1:安装 gvu(10 秒) Linux / macOS: curl -fsSL gomodvanityurls.com/install.sh | bash Windows (PowerShell): powershell -ExecutionPolicy ByPass -c "irm https://gomodvanityurls.com/install.ps1 | iex" 安装完成后验证: $ gvu --version gvu version 0.1.5 (built: 2026-07-09T10:00:00Z) Step 2:添加你的第一个 Vanity URL(20 秒) 假设你有一个 GitHub 仓库 https://github.com/yourorg/awesome-lib,你想让它可以用 gomod.io/yourname/awesome-lib 来导入。 $ gvu add gomod.io/yourname/awesome-lib https://github.com/yourorg/awesome-lib.git ✔ Route created successfully! ═══════════════════════════════════════════════════════════ ┃ Route ID: m_abc123 ┃ Vanity Path: gomod.io/yourname/awesome-lib ┃ Target Repo: https://github.com/yourorg/awesome-lib.git ┃ Quota: 1 / 5 used (4 slots remaining) ═══════════════════════════════════════════════════════════ 搞定了。 一个匿名账户会自动创建,无需注册、无需邮箱、无需信用卡。 ...

2026年7月12日 · Tony Bai

从 IP 地址到品牌域名:一个 Go 团队的 Vanity URL 之旅

“10.0.1.50 是什么服务?” 老张盯着屏幕上的报错信息,眉头紧锁。 build failed: cannot find module "10.0.1.50/user-service": module lookup disabled by GOPROXY=off 他转头问旁边的新人小李:“你知道 10.0.1.50 是什么服务吗?” 小李一脸茫然。他才入职第三天。 这是老张所在公司——一家中型互联网金融公司——的日常。平台组有 50 多个 Go 微服务,全部用内网 IP 地址作为 import path。没有人觉得有什么不对——直到上周服务器搬迁。 背景:IP 地址做 import path 的"原始时代" 两年前,平台组刚开始用 Go 的时候,一切都很简单。5 个微服务,代码放在自建 GitLab 上,import path 直接写 IP: import ( "10.0.1.50/user-service" "10.0.1.50/order-service" "10.0.1.51/payment-gateway" ) “能用就行”,当时没人多想。 但两年后,微服务从 5 个增长到了 50 多个。团队从 8 人扩张到 30 人。问题开始浮现: 问题一:IP 地址毫无可读性 // 这段代码你能看懂每个依赖是什么吗? import ( "10.0.1.50/user-service" // ✅ 还行 "10.0.1.51/pay-gw" // ❓ 支付网关? "10.0.1.52/cfg-svc" // ❓ 配置中心? "10.0.1.53/msg-queue" // ❓ 消息队列封装? ) 新人入职第一天就要记住"IP 地址 ↔ 服务名"的映射表。老张自己都经常搞混 10.0.1.52 和 10.0.1.53。 ...

2026年7月12日 · Tony Bai

为什么你的 Go 私有模块不该直接用 GitHub 路径

一个真实的噩梦 去年,我朋友老张的公司做了一个"很正常的决定"——把代码从 GitHub Enterprise 迁移到自建 GitLab。 听起来不复杂对吧?代码搬过去,CI 改改,完事了。 直到他们发现:公司 200 多个 Go 微服务的 import path 全是以 github.com/their-org/ 开头的。 迁移代码仓库只需要一个周末。但修改所有下游服务的 import path?3 个工程师干了两个星期。改完还要回归测试,又是一周。 老张事后跟我说了一句话,我至今记得: “如果当初用了 vanity URL,这一切只需要改一条 DNS 记录。” 这篇文章,就是写给还没踩这个坑的你。 四大隐患 隐患一:平台锁定——换 Git 服务 = 改所有 import Go 模块的 import path 就是它的身份标识。当你写: import "github.com/your-org/user-service" 你实际上是在说:这个模块永远住在 GitHub 上。 想迁移到 GitLab?改 import。想迁移到 Gitea?改 import。想迁移到自建 Gitea?还是改 import。 而且不只是改一个地方——是所有引用了这个模块的项目、所有下游服务、所有 go.mod 文件。对于中型团队,这可能意味着 数百个文件的批量修改 + 全量回归测试。 这不是假设。Go 社区里几乎每年都有公司因为 Git 平台迁移而经历 “import path 大逃亡”。 隐患二:IP 地址和内网信息裸奔 比 GitHub 锁定更危险的是自建 Git 服务器的场景。很多公司内部直接用 IP 地址或内网域名: ...

2026年7月12日 · Tony Bai