一个单行代码的 npm 库,竟然让数百万个 JavaScript 项目崩溃了...

javascript.png

技术编辑:徐九丨发自 北京
SegmentFault 思否报道丨公众号:SegmentFault


上周六,一个 JavaScript 库的更新让近乎整个 JavaScript 生态系统陷入了混乱,据分析机构粗略统计,数百万个项目都受到了影响。

最让人意想不到的是,调用造成混乱的这个库,只需要一行代码...

一行代码的威力

导致问题的库名称为「is-promise。这个库由两行原始代码组成,开发者可以通过单行调用在项目中使用它。它的功能也很简单,是让开发者测试一个 JavaScript 对象是否是「Promise」,在项目中使用时,函数会返回一个是或不是的布尔结果(“ true”或“ false”)

尽管只有两行执行代码,但「is-promise」库已经是当今最流行的 JavaScript npm 库之一。根据 GitHub 的数据显示,该库目前已经被 340 万个项目调用过,并被 766 个其他 JavaScript 库作为依赖库使用。

clipboard.png

这次新版本最主要的更新内容,是使其可以作为 ES 模块(JavaScript 语言使用的标准化模块系统)。然而,这个最新版本并没有遵守正确的 ES 模块使用标准。更新后,在构建链中使用「is-promise」的项目会不正确的 ES 模块支持而报错。

这个错误造成的影响是非常迅速和巨大的,甚至很多大型的 JavaScript 项目都受到了影响。其中包括 Facebook 的 Create React App(创建React应用的标准模板)、Google 的 Angular.js 框架和 Firebasse-tools、Amazon 的 AWS Serverless CLI、Nuxt.js、AVA 等。

clipboard.png

对此,「is-promise」团队迅速响应发布了一次更新,但并没有设法去修复这个问题,而是在 v2.2.2.2 版本中回滚了对 ES 的模块支持。

2016 年的「前车之鉴」

JavaScript.png

这其实是第二个 JavaScript 生态系统中,「千里之堤毁于蚁穴」的事故了。早在 2016 年,就有过前车之鉴。

2016 年 3 月,一个仅有 17 行代码的 JavaScript 库作者突然决定取消发布这个工具库,进而导致成千上万的相关项目受到了影响,当时在各大论坛和社区引起了开发者们的广泛讨论。

和 2016 年一样,此次「is-promise」事件也引发了开发者圈内的热议,并引发了对于生态系统中是否需要单行库的讨论。

有一派认为,当开发者创建的库只占几行代码,但却用于很琐碎的操作时,模块化有一些不太必要。

但还有一种观点认为,这类项目的模块化是必要的,因为通过这种方式,某一项任务可以在一个通用的模块内管理,而不是让成千上万的开发人员在自己的项目中以不同的方式处理。

关于模块化的讨论已经有好几年了,但至今也没有答案。

其实,现在的软件开发中不使用第三方开发者提供的现成组件是根本不可能的。当前前端比较流行的几大框架,核心思想都离不开组件化,也只有这样,才能大大的提高项目开发速度。但这也导致了很多的不可控风险,就像这次的事故。

对此,你怎么看?你觉得应该如何规避类似的风险?

特约评论员:祁宁@joyqi

成也 npm 败也 npm,我已经记不清这是 npm 第几次发生类似的事情了。node 包的灵活性让它蓬勃发展,你所需要的任何功能基本都能找到相应的包去实现,这就让开发者越来越懒,哪怕这个功能如此简单。开发者认为所有的包都得到了精心的维护,但当一个系统中引入的不确定性越多,它崩溃的可能性就越高。所以奉劝每个开发者在 npm install 的时候多想想你是否真的需要它吧。


参考资料:

ZDNet:《Another one-line npm package breaks the JavaScript
ecosystem》rossaprimavera:《Upgrading the popular library in JavaScript
has crashed millions of projects》

clipboard.png

阅读 5k

推荐阅读

SegmentFault 思否对开发者行业的洞见、观察与报道

17396 人关注
109 篇文章
专栏主页
目录