← 文章 / 编程开发
Hacker News 1天前 · 2026-09-28 07:29:21 · 2 阅读

别让 Go 代码与 GitHub 绑死

Go 语言的一个优点是用代码的获取位置来定义命名空间。例如,如果你的代码托管在 http://github.com/thetrueares/boneclone,只需写 `import "github.com/thetrueares/boneclone"`,Go 就会自动通过 git 拉取依赖。这让开源库的 bug 报告入口一目了然,也让分发 Go 库变得简单,无需依赖中央包管理系统。对很多人来说,代码地址直接等于 Git 托管平台,但这带来一些隐患。建议改用自定义域名,原因如下。

问题所在

使用 Git 托管地址作为代码路径,会让代码与特定托管平台紧耦合。一旦迁移到 GitLab,就必须修改代码,否则拉取的仍是旧版本。由于迁移成本较高,许多团队被锁定在 GitHub 上。这在 Go 社区中几乎成了默认惯例,但确实不合理。

我见过一家公司因更换代码位置的工作量太大且无暇顾及,索性同时使用 GitLab、GitHub 和 Azure DevOps 三个平台,只为简化操作。这也正是我开发 Boneclone 的初衷——支持同时向多个 Git 平台复制骨架代码。结果这家公司不得不为三个托管服务付费,直接增加了成本。

解决方案

使用自定义域名,例如 go.iain.rocks、go.uber.org、go.mongodb.org 等。这样只需修改域名的指向即可。例如,go.iain.rocks/boneclone 指向 github.com/thetrueares/boneclone;如果日后迁移到 GitLab,只需更新解析,最终用户的安装命令保持不变。

我认为,所有使用 Go 的商业开发团队都应为内部库和包使用自定义域名作为命名空间,这是一种避免无意义耦合的简单方式。

以下是我的配置示例,你可以将其用于自己的项目。

Nginx.conf

server {
    server_name go.iain.rocks;
    root /var/www/go.iain.rocks;
    index index.html;

    location / {
        # 检查查询字符串是否“不包含” 'go-get=1'。
        # '~' 用于区分大小写的匹配。
        if ($args !~ go-get=1) {
            # 这是人类访问者。永久重定向到 GitHub。
            # $request_uri 将是路径,例如 /boneclone
            return 301 https://github.com/that-guy-iain$request_uri;
        }

        # 如果是 Go 工具(带有 ?go-get=1),则像之前一样提供 HTML 文件。
        try_files $uri $uri/ =404;
    }

    # --- 来自 Certbot 的 SSL 配置应保留在此处 ---
    listen 443 ssl;
    listen [::]:443 ssl;
    ssl_certificate /etc/letsencrypt/live/go.iain.rocks/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/go.iain.rocks/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}

# 从 HTTP 到 HTTPS 的重定向块也应保留。
server {
    listen 80;
    listen [::]:80;
    server_name go.iain.rocks;
    return 301 https://$host$request_uri;
}

index.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="go-import" content="go.iain.rocks/boneclone git https://github.com/that-guy-iain/boneclone">
        <meta name="go-source" content="go.iain.rocks/boneclone https://github.com/that-guy-iain/boneclone https://github.com/that-guy-iain/boneclone/tree/master{/dir} https://github.com/that-guy-iain/boneclone/blob/master{/dir}/{file}#L{line}">
    </head>
    <body>
    </body>
</html>
原始来源: Hacker News

评论 (0)