package.json 对比 go.mod:版本字段去哪了?

如果你从 JavaScript 转到 Go,有一件事会让你感到惊讶。

package.json 文件中,版本号就在最顶部。你可以直接读取它,可以在 pull request 中修改它,也可以搜索它。它是一个实实在在存在于代码中的事实。

现在打开一个 go.mod 文件。版本号并不在那里。

这不是一个错误,而是一种选择。

Go 不会为你的模块使用版本字段。相反,Go 使用 git tags。

在 Go 中设置版本,你需要这样做:

git tag 是唯一的真理来源(single source of truth)。当有人运行 go get 时,Go 会查看你的仓库标签以找到正确的 commit。

这种设计有一个巨大的优势:版本永远不会指向错误的代码。在 npm 中,发布的代码和标记的源码可能会产生偏差。而在 Go 中,它们是同一回事,因为版本就是指向一个 commit 的指针。

然而,这会在多个方面改变你的工作流:

大多数其他生态系统都将版本保存在文件中:

Go 与众不同。它仅依赖 git tags。

如果你希望你的 Go 二进制文件显示整洁的版本号,可以在构建过程中使用 ldflags 进行注入。许多开发者还会使用像 goreleaser 这样的工具来自动化 tag 和发布流程。

这两种模型代表了不同的优先级:

Go 选择标签模型是为了确保清单(manifest)始终与代码保持一致。

对于那些发布 Go 代码的开发者:在日常工作中,这种仅基于 Tag 的模型体验如何?你会改变它吗?

来源:https://dev.to/dalirnet/packagejson-vs-gomod-where-did-the-version-field-go-3301