路由税

你的团队已经用上了 vanity URL。导入路径干净了,不再绑定平台,看着就舒服:

import "go.mycorp.com/auth"
import "go.mycorp.com/config"
import "go.mycorp.com/logger"

然后团队扩张了。每个迭代都有新服务上线。每个新服务都需要一条 gvu add 命令:

gvu add go.mycorp.com/auth https://github.com/mycorp/auth.git
gvu add go.mycorp.com/config https://github.com/mycorp/config.git
gvu add go.mycorp.com/logger https://github.com/mycorp/logger.git
gvu add go.mycorp.com/cache https://github.com/mycorp/cache.git
gvu add go.mycorp.com/queue https://github.com/mycorp/queue.git
# ... 还有 45 个

50 个仓库,50 条路由。每新建一个仓库就要提个 PR 更新路由配置。谁忘了?新服务的 go get 直接报错,整个团队被卡住。

这就是路由税——维护 vanity URL 映射的人工开销,而这些映射本该是自动的。


一条规则覆盖所有仓库

通配路由消灭路由税。不需要逐个添加仓库,你只需要写一条规则覆盖路径前缀下的所有仓库:

gvu add 'go.mycorp.com/*' 'https://github.com/mycorp/*.git'

搞定。一行命令。现在 mycorp GitHub org 下的每个仓库都自动可用 vanity 路径导入:

import "go.mycorp.com/auth"       // → github.com/mycorp/auth
import "go.mycorp.com/config"     // → github.com/mycorp/config
import "go.mycorp.com/logger"     // → github.com/mycorp/logger
import "go.mycorp.com/newthing"   // → github.com/mycorp/newthing(立刻可用!)

在 GitHub 上创建了个新仓库?立刻可以用 vanity 域名 go get 拉取。不用改配置,不用提 PR,不用等人。

这是 Repo 通配(W1)——vanity path 中的 * 匹配任意单个路径段,repo URL 中的 * 被匹配到的名称替换。


Monorepo?用 Subdir 通配

如果你的模块在 monorepo 里,而不是独立仓库呢?

monorepo/
├── go/
│   ├── auth/go.mod
│   ├── config/go.mod
│   ├── logger/go.mod
│   ├── cache/go.mod
│   └── ... 还有 20 个

你不需要 repo 通配。你需要的是 Subdir 通配(W2)

gvu add go.mycorp.com/libs https://github.com/mycorp/monorepo.git '--subdir=*'

monorepo 中任意子目录下的 Go 模块都自动可导入:

import "go.mycorp.com/libs/auth"     // → monorepo,subdir go/auth
import "go.mycorp.com/libs/config"   // → monorepo,subdir go/config
import "go.mycorp.com/libs/cache"    // → monorepo,subdir go/cache

往 monorepo 里加新模块?自动可导入——不需要改任何路由。

注意:Subdir 通配需要每个模块的 go.mod 声明 Go 1.25+。完整配置参见我们的 monorepo 教程


实战场景

场景 1:多团队组织

公司有三个团队,各有独立的 GitHub org:

# 平台团队 — 15 个仓库
gvu add 'go.mycorp.com/platform/*' 'https://github.com/mycorp-platform/*.git'

# 数据团队 — 12 个仓库
gvu add 'go.mycorp.com/data/*' 'https://github.com/mycorp-data/*.git'

# 基础设施团队 — monorepo 里的 8 个模块
gvu add go.mycorp.com/infra https://github.com/mycorp-infra/monorepo.git '--subdir=*'

三条规则。三十五个模块。零维护。

场景 2:覆盖特定仓库

有些仓库不符合通配规则。可能它在另一个 org 里,或者它是一个 fork。用精确路由覆盖:

# 通配规则覆盖大部分仓库
gvu add 'go.mycorp.com/*' 'https://github.com/mycorp/*.git'

# 但 auth 已经迁到了另一个 org
gvu add go.mycorp.com/auth https://github.com/security-team/auth.git

# logger 是一个维护中的 fork
gvu add go.mycorp.com/logger https://github.com/upstream/logger.git

gvu 通过优先级规则解决冲突:

优先级规则类型匹配场景
1(最高)精确路由特定仓库的覆盖
2Subdir 通配(W2)Monorepo 子包
3(最低)Repo 通配(W1)org 级别的兜底

精确路由永远优先于通配。这让你可以用宽泛的默认规则加上精准的例外。

场景 3:渐进式采用

不想一步到位?先用精确路由管理最常用的模块,路由数量多了再加通配:

# 第 1 周:就几个模块
gvu add go.mycorp.com/auth https://github.com/mycorp/auth.git
gvu add go.mycorp.com/config https://github.com/mycorp/config.git

# 第 5 周:太多了,管不过来了
gvu add 'go.mycorp.com/*' 'https://github.com/mycorp/*.git'
# 精确路由仍然有效——它们优先级更高

底层原理

当开发者运行 go get go.mycorp.com/auth 时,Go 工具链向 https://go.mycorp.com/auth?go-get=1 发送请求。gvu 的服务器:

  1. 先查精确路由——有没有 go.mycorp.com/auth 的精确规则?
  2. 再查 Subdir 通配(W2)——有没有 W2 规则的前缀匹配?
  3. 最后查 Repo 通配(W1)——有没有 W1 规则的模式匹配?

当通配命中时,服务器动态生成 go-import meta 标签:

<!-- W1 匹配:go.mycorp.com/auth → github.com/mycorp/auth -->
<meta name="go-import" content="go.mycorp.com/auth git https://github.com/mycorp/auth">

<!-- W2 匹配:go.mycorp.com/libs/auth → github.com/mycorp/mono subdir go/auth -->
<meta name="go-import" content="go.mycorp.com/libs/auth git https://github.com/mycorp/mono go/auth">

没有静态 HTML 文件。没有 Nginx 配置。meta 标签从通配规则动态生成。


前提条件

通配路由是 Pro 功能。你需要:

条件说明
Pro 账户运行 gvu subscribe — 50 条路由、自定义域名、通配
自定义域名go.mycorp.com DNS CNAME 指向 gvu
不支持 gomod.io通配需要你自己的域名

为什么不支持 gomod.io?因为 gomod.io 下的通配会让任何人声明该域名下的任意路径,存在安全风险。

配置自定义域名

# 1. 添加 CNAME 记录
go.mycorp.com  CNAME  gomodvanityurls.com

# 2. 用 gvu 验证
gvu domain add go.mycorp.com
gvu domain verify go.mycorp.com

# 3. 创建通配路由
gvu add 'go.mycorp.com/*' 'https://github.com/mycorp/*.git'

HTTPS 证书自动签发——不需要手动管理证书。


限制与注意事项

几点需要记住:

  • 每条规则只能有一个 *——不能写 go.mycorp.com/*/*(路径中两个通配符)
  • W1 和 W2 互斥——同一条路由只能用 repo 通配或 subdir 通配,不能同时使用
  • 每条通配路由占 1 个 Pro 配额(共 50 个)
  • Shell 引号很重要——包含 * 的参数必须用单引号包裹:
# ✅ 正确
gvu add 'go.mycorp.com/*' 'https://github.com/mycorp/*.git'

# ❌ 错误——shell 会展开 glob
gvu add go.mycorp.com/* https://github.com/mycorp/*.git

前后对比

维度逐个添加路由通配路由
配置每个模块一条命令每个 org/monorepo 一条命令
新建仓库必须先加路由立即可用
路由数量N 个仓库 = N 条路由N 个 org = N 条规则
维护成本每次新服务都要更新设一次,永久生效
例外处理不适用精确路由优先覆盖

总结

如果你有超过 5 个 Go 模块,通配路由立刻能回本:

# 多仓库 org:一条规则覆盖全部
gvu add 'go.mycorp.com/*' 'https://github.com/mycorp/*.git'

# Monorepo:一条规则覆盖所有子包
gvu add go.mycorp.com/libs https://github.com/mycorp/mono.git '--subdir=*'

# 混合使用精确覆盖
gvu add go.mycorp.com/special https://github.com/other/special.git

每个 org 一条规则。每个 monorepo 一条规则。精确路由处理例外。这就是一个 50 模块组织的完整路由配置。

升级到 Pro,5 分钟内配好通配路由。