一名开发人员取消发布包含 11 行代码的软件包,导致互联网崩溃

2025-06-04

一名开发人员取消发布包含 11 行代码的软件包,导致互联网崩溃

所有 Javascript 开发人员可能都曾在其一生中的某个时刻使用过npm。npm是node.js的默认包管理器。对于那些不知道 npm 是什么的人来说,npm – Node Package Manager的缩写是 JavaScript 编程语言的包管理器。npm, Inc. 是 GitHub 的子公司。npm 可以管理特定项目依赖的包,允许用户重用已经分发并存在于 npm 远程注册表中的模块或代码片段。您的项目所依赖的包本身可以依赖于另一个包,而另一个包又依赖于另一个包,依此类推。但好处是,使用 npm 您不必担心其他依赖项,npm 会为您处理并免费完成所有工作。

现在我们知道了 npm 是什么以及它是如何工作的,让我们看看 2016 年 3 月 22 日发生了什么,导致 React、Node、Babel 等常用的软件包崩溃,世界各地的多名 JavaScript 程序员在尝试运行他们的代码时收到奇怪的错误消息。

背景

Azer Koçulu是一位开源开发者,他一直在 npm 上发布和维护他的软件包,供其他开发者使用并添加到他们的软件包中。在他 npm 上发布的约 270 个软件包中,有一个名为kik,它帮助程序员为他们的项目设置模板。Kik
也是一款免费的即时通讯移动应用程序的名称,该应用程序可在 Android 和 iOS 上使用,由总部位于加拿大安大略省的Kik interactive公司开发。

电子邮件

有一天,Koçulu 收到了 Kik 一位专利代理人的邮件,要求他重新命名他的软件包,kik因为他们计划在 npm 上发布一个软件包,而 Koçulu 的 NPM 软件包可能会造成混淆。完整的邮件内容可以在这里找到,但大致来说,Azer 拒绝了 Kik 的请求。Kik 的专利代理人 Bob Strattonkik向 NPM 团队转达了 Kik 的命名请求,并再次提到了该公司的商标和潜在的混淆。NPM
决定站在 Kik 一边,kik从 Azer 手中夺走了这个名字,将这个名字交给了 Kik。

模块的解放

在发现 NPM 站在公司一边后,Koçulu 写信给 NPM,表示他希望 NPM 下架他发布的所有软件包,或者让他们告诉他如何快速下架。Koçulu 发出这封邮件两天后,也就是 3 月 22 日星期二,全世界的程序员都只能眼睁睁地看着构建失败和安装失败。在多行错误信息中,其中一行内容如下:

npm ERR! 404 'left-pad' is not in the npm registry.
Enter fullscreen mode Exit fullscreen mode

这个错误的意思是,你尝试构建/运行的代码需要一个名为 的包,left-pad但 npm 注册表(我们在本文开头提到的注册表)中不存在。这个名为“left-pad”的包去哪儿了?
Koçulu 似乎按照他在电子邮件中所写的方式做了,他取消了在 npm 上发布的所有包,而left-pad就是 Koçulu 发布的包之一。他写了一篇博文,解释了他取消发布所有模块的原因。“这种情况让我意识到,NPM 是某些人的私人领地,企业比人民更强大,我从事开源是因为‘权力归人民’,”Koçulu 在他的博客中说道。

取消发布 left-pad

为了修复全球所有出现问题的项目和软件包,NPM 首席技术官兼联合创始人 Laurie Voss 于 3 月 23 日决定采取一项非同寻常的举措,恢复了NPM 上应用程序所需的尚未发布的 left-pad 0.0.3 版本。他推文中写道:“鉴于问题的严重性和广泛性,我们采取了前所未有的行动,这绝非轻率之举。” 此后,所有出现问题的软件包都开始成功构建和运行,从而修复了互联网。Laurie 还表示:“即使在 npm 内部,我们也未必一致认为这是正确的决定,但我无法想象每秒数百个构建失败而不去修复它。” 虽然我同意他的观点,但这也让我开始思考接下来要讨论的一些问题。

left-pad 是什么?

让我们看一下 left-pad 的内容,并尝试弄清楚为什么世界各地有这么多项目使用这个包。left
-pad,顾名思义,用字符或空格填充字符串的左侧,整个包仅包含 11 行代码。11。这就是完整的 left-pad。

module.exports = leftpad; 
function leftpad (str, len, ch) {
   str = String(str);
   var i = -1;
   if (!ch && ch !== 0) ch = ' ';
   len = len - str.length;
   while (++i < len) {
     str = ch + str;
   }
   return str;
}
Enter fullscreen mode Exit fullscreen mode

为什么这会导致 NPM 上这么多包崩溃?

2016 年 3 月 22 日,React、Babel 和 NPM 上许多其他备受关注的软件包崩溃了,因为所有这些软件包和项目都依赖于软件包中一个简单的左填充字符串函数left-pad。大多数遇到这些构建错误的程序员可能甚至没有听说过 left-pad 这个名字,但他们的代码崩溃了,因为他们的应用程序依赖于一些软件包,而这些软件包又依赖于一些软件包,最终,其中一个依赖项可能就是left-pad
理想情况下,程序员不必担心所有这些依赖关系,因为 NPM 会为他们处理这些问题,而且一直以来都很可靠。但在这种情况下,该软件包尚未发布,npm 无法找到此依赖项,从而导致这些无法预料的错误。

为什么这么多的软件包都依赖于 left-pad 呢?

left-pad 只有 11 行代码,只是一个作为模块导出的函数,很多软件包都依赖于它,而不是这些软件包的开发人员自己为 left-pad 编写一个基本函数。对于一个熟练的程序员来说,编写这样的函数几乎只需要几分钟,但他们却决定依赖另一位开发人员来完成。将多个第三方依赖项或软件包绑定在一起,并用最少的代码开发项目并不是理想的做法。任何第三方依赖项的问题都会导致代码中断,您将需要另一位开发人员修复他们的工作,以便您的项目能够再次正常运行。例如,当像 Facebook 这样的 Web 服务间接依赖于其他程序员编写的代码时,这必须被视为一个严重的问题,而这些程序员甚至不知道他们的代码可能会产生什么影响。

多少依赖项才算过多依赖项?

我们是不是已经懒到需要一个来检查一个对象是否为 Array 了?这个包只有一行代码,在我写这篇文章的时候,每周下载量高达 39,001,468 次。我们真的需要发布只包含一个函数的包吗?我们是否应该为了那些我们可以轻松编写的几行代码而创建依赖包?我认为这种软件开发方式需要改变,应该在提供一系列相互关联、复杂功能的“
” 上创建依赖。为什么要导入一个用于加、减、乘的包,而不是导入一个提供所有数学功能的包呢? 为了简化代码编写,我们不断地添加依赖项,只为了实现最小的功能,这会导致代码维护困难,尤其是在你无法控制第三方包的情况下,并且会增加故障点。 应该尽量减少依赖项,并且只依赖那些提供许多复杂功能的知名库,这些功能自己编写起来会非常困难/耗时,这样冒点错误的风险才是值得的。

对所有程序员来说,我想说的是,如果在不久的将来,你的项目中需要用到一个小型的简单功能,那就选择自己写几行代码,而不是添加对未知包的依赖。以那些选择直接或间接依赖 11 行代码而不是自己写代码的沮丧程序员为例。

我写这个博客并不是为了讨论 Kik、NPM 或 Azer 采取的行动是否符合道德/合法性,因为我不是该领域的专家,我对此的看法并不成立。

我写这篇博客的目的是讨论依赖如此多小型 API(单行函数也算 API 吗?)的方法论是如何带来灾难性的,并重新思考这种编程方式。
我还建议你浏览一下这篇Reddit 帖子,看看其他程序员对此事的看法。

本博客的所有内容均来自谷歌搜索、阅读文章等,有些地方可能存在错误,如果我遗漏了什么,请联系我。

注意:特色图片由xkcd提供,所有版权归艺术家所有。

希望你喜欢这篇文章!
谢谢。

文章来源:https://dev.to/chaitanyasuvarna/how-a-developer-broke-the-internet-by-un-publishing-his-package-containing-11-lines-of-code-31ei
PREV
前端最佳实践(以 Vue.js 为特色)前端 Web 开发的最佳实践
NEXT
干净的代码对于初创公司成功的重要性 个人建议