go mod 是 rsc 主导设计的 Go 版本管理工具,借鉴了 Google 内部的高大上版本管理方式,摒弃了开源社区的版本管理成功经验,借助 MVS 算法,希望能够走出一条不一样的路,然而从发布以来给广大 Gopher 带来了各种各样的麻烦。本文简单列举一部分罪状,Google 的并不一定总是世界的。

当然,随着 Go 1.16 的发布,其中有些罪证可能已经不成立了,读者可以自行甄别。

Go 命令的副作用

Go list,Go test,Go build,所有命令都会去拉取依赖,有些库是用被墙的服务做了重定向,只是执行一下 go test,然后就被卡一年是家常便饭。

按照 "By design" 的说法,Google 内部的依赖库版本都会尽量使用能够兼容的最新版本。对于墙内的我们来说,我不管执行什么 Go 命令怎么都卡。逐渐患上 go test PTSD。

解法:配置 GOPROXY 代理,虽然拉取依赖还是慢。

形同虚设的 semver 规范

社区里不遵守 semver 规范的库很多,有的开源库在 1.7.4 ~ 1.7.5 中进行了 breaking change,而按照 semver 的定义,这是不应该发生的。go mod 过度高估了开源社区的节操。

一开始,我们以为这只是社区的节操问题,直到我们碰到了 gRPC。

好样的哦,Google 工程师。

无法应对删库

leftpad 悲剧重演

js 社区使用集中式的 npm 来管理依赖,在几年前发生过一次因为作者删库,导致几乎所有互联网巨头的前端项目全部 build 失败的悲剧。同时 js 社区也进行了一些反思 how one programmer broke the internet[1],have we forgotten how to program[2]。

npm 好歹还是集中式的版本管理方式,Go 号称分布式,但大多 Go 的依赖库都是存在 Github 上,如果 Github 上的原作者删除了该库,那么也会导致大多数的依赖用户 build 失败。

即使看起来我们可以靠 go.mod 和 go.sum 来实现 reproducible build,实际的情况是,像 k8s 这样的项目,依然会把庞大的依赖库放在自己 repo 的 vendor 里。

在笔者从 dd 离职时,也曾经不小心删除过一个认为应该没有人再依赖的个人库,当时给前同事们也造成了一些麻烦。

Github release/tag 水土不服

在 Github 上发布 lib 的 release,或者给某个 commit 打 tag 之后,我们依然可以对这些 tag 和 release 进行编辑:

我们经常看到,有些库的作者在发布一个 release 之后,又删除了这个 release,或对这个 release 进行了编辑。对于用户来说,这样就会依赖一个已经“消失”了的版本,在不存储 vendor 的情况下,reproducible build 沦为笑谈。

goproxy 的实现并不统一

不知道是否是因为 goproxy 并无规范,在使用不同的代理帮助我们加速下载依赖时,会出现各种不同的错误。

例如作者 A 开发的 goproxy,在某个库不存在时,会返回 404。而作者 B 开发的 goproxy,在某个库不存在时,会返回 500。着实令人困惑。

而 goproxy 本身的实现基本都是惰性下载,所以新发布的库,我们要走 goproxy 来测试时,就需要手动 go get 触发。而大多 goproxy 的实现并没有查询功能,goproxy 服务内部到底什么时候同步好了,可以 go get 了,还是 go get 的过程中发生失败了。作为用户是不可查的。

go get 到的 lib 版本在 go build 时被修改

在 go get 时,可以 go get lib@ver 来获取指定版本的依赖,但是在 go build 时可能发现又被修改成了别的版本(比如被升级了),非常反直觉。

我们想要锁定具体的版本,只能使用 replace。

版本信息扩散

由于 go mod 的设计,版本信息被包含在了 import 路径中。当依赖库从 v1 升级至 v2 时,几乎一定意味着我们代码中大量的 import 路径需要修改。

修改不兼容的 api 就挺累的了。

go.sum 合并冲突

因为上面讲到的一系列问题,go.sum 在多人维护的大项目上,经常会发生变动,也就经常会有冲突。对于中心化版本管理系统来说,这个问题根本就不存在。对于 go mod 来说,go.sum 合并本来是个纯追加逻辑。

但这些冲突还是会浪费我们的时间。

如果你也曾经被 go mod 烦到骂娘,欢迎在评论区分享你的故事。

同时,也欢迎关注作者的公众号:

欢迎关注 TechPaper 公众号。

TechPaper

[1]

how one programmer broke the internet: https://qz.com/646467/how-one-programmer-broke-the-internet-by-deleting-a-tiny-piece-of-code/

[2]

have we forgotten how to program: https://www.davidhaney.io/npm-left-pad-have-we-forgotten-how-to-program/

Go mod 七宗罪相关推荐

  1. 驳“AJAX 的七宗罪”

    (本文转载自"Java视线",原文地址:http://forum.javaeye.com/viewtopic.php?t=13844,作者dlee) (AJA X的七宗罪:http ...

  2. 驳AXAJ的七宗罪 (转)

    我不带任何主观色彩来评一下这个所谓的 "AJAX 的七宗罪". 1.连带着 Flash 和 Ajax 一块骂了. 引用:没有链接的web就像森林中迷路的羔羊,这句看似广告语,其实是 ...

  3. OpenStack进入第二阶段需要解决的“七宗罪”

    以下内容节选编译自分析人士Steve Chambers近期撰写了一份OpenStack市场研究报告,发表在Wikibon Premium网站.报告的名称为<OpenStack进入第二阶段> ...

  4. 好产品要满足人性七宗罪

    好产品要满足人性"七宗罪": 作为一个有20年实战经验的互联网老兵,周鸿祎称得上是一个优秀的产品经理,一手打造了众多国民级的产品. 每个人都有成为产品经理的潜质.但是," ...

  5. 产品经理学习---人性七宗罪:打造完美产品的金钥匙

    那些我们不愿承认的人性七宗罪,恰好是打造产品的最佳依据,正视人性之恶,打造产品之美. 但丁在<神曲>中称人有七宗罪:傲慢,嫉妒,暴怒,懒惰,贪婪,贪吃和色欲.个人认为七宗罪其实是人的本能, ...

  6. CSDN Blog 之七宗罪

    CSDN Blog 之七宗罪 第一,不稳定,就为这个,我曾一度离开这里,不过终究还是有点怀念我写的那点儿东西.目前的稳定性比以前有所改善. 第二,我习惯用firefox,csdn的blog大体上还算兼 ...

  7. 让你此生难成大器的七宗罪

    是,你没看错......说的就是你--说的就是你呢! 我此刻死盯着你的眼睛(好吧,也不是那么名副其实的"盯着",因为你看到的是这篇文章不是我,但请想象,我现在正在死盯着你,我的镭射 ...

  8. 电信资费七宗罪,终端的故事

    电信资费七宗罪,终端的故事 文 | 宁宇 你的手机是自己买的,还是运营商连合约一起卖给你的?运营商让你以优惠的价格甚至零元拿到了终端,运营商获得了什么利益?为何如今客户对合约机从爱走向恨?这条走了十几 ...

  9. Jetpack MVVM 七宗罪之四: 使用 LiveData/StateFlow 发送 Events

    久违的 " Jetpack MVVM 七宗罪 " 系列,今日再开.本系列主要盘点 MVVM 架构中各种常见错误写法,并针对性的给出最佳实践,帮助大家掌握 Jetpack 组件最正确 ...

最新文章

  1. linux上安装nero4j 关系数据库
  2. mxnet Module load
  3. 格“物”致知:多模态预训练再次入门
  4. 如何使java中double类型不以科学计数法表示
  5. 学习笔记(44):Python实战编程-单击事件
  6. Java commit()_Java XAResource.commit方法代码示例
  7. QQ 一键加群、扫二维码加群 - 腾讯官方API文档接入
  8. sprk sql自定义UDF函数
  9. java虚拟机工作原理_java虚拟机原理及工作原理都是什么?java虚拟机如何运行?...
  10. Java 函数式编程的妙用
  11. NoteExpress 文献管理软件及使用相关问题
  12. 67tool.com 即用即走的在线工具箱
  13. 1395786-30-7,DBCO Maleimide,DBCO-Mal
  14. T83310 【音乐会】二重变革
  15. Page Cache 与 Kafka 那些事儿
  16. python 柱状图折线图共用一个图例_使用python的seaborn绘制折线图与柱状图的组合图...
  17. mysql解析json_mysql解析简单json字符串
  18. maven surefire的executions配置
  19. Scrapy爬虫轻松抓取网站数据
  20. php 上传图片方法

热门文章

  1. linux cat 进程,Linux下CAT程序的C实现
  2. Java 中,类、类对象、泛型之间的转换
  3. 阿里RocketMQ是怎样孵化成Apache顶级项目的?
  4. springboot 入门教程(1)
  5. mongodb - 查看正在执行的操作
  6. 【Android开发】消息处理类(Handler)与消息类(Message)介绍
  7. 关于相对布局RelativeLayout的各种属性介绍
  8. Web最基本的弹出窗口代码(javascript)
  9. Releasing Contexts 释放上下文
  10. windows mobile创建文本文件并用word打开