left-pad事件,代码优化| 豆包MarsCode AI刷题

9 阅读4分钟

left-pad事件出现的时代,node发展的很快出现了很多包和模块,然后就出现了这么一个哭笑不得的事情:leftpad 事件是2016年3月发生的一起著名的 npm(Node.js 包管理器)生态系统中的事件,它揭示了开源软件供应链中的一些重要问题。这个事件对软件开发社区产生了深远的影响,并提供了许多关于依赖管理和软件供应链安全的教训。

发生了什么?

Azer 是一名 Javascript 程序员,他写了 273 个 Javascript 封包放在 npm 上供大家使用。一个叫 left-pad 的封包包,虽然只有 11 行,但被上千个项目用到,其中包括著名的 babel 和 react-native。

module.exports = leftpad;
function leftpad(str,len, ch){ str = String(str); 
var i = -1; ch || (ch = ' ');
len = len - str.length;
while(++i < len){ str = ch + str; } }

一天 Azer 收到一封邮件。邮件上说,“Hi, Azer. 我们是 kik 公司的,我们要发布我们的封包 kik, 发现 kik 这个名字已经被你占用了。你能把名字改改嘛?”。

Azer 内心 os “大哥,有木有搞错,这个名字我已经用了”,便回了一封邮件说,“我拒绝”。

kik公司收到回复之后,又给 Azer 发了一封关于敬酒罚酒的邮件,Azer 再拒绝。。。就这样几个回合之后, kik 公司灵机一动,心想“我干嘛和你死磕,我找 npm”,于是给 npm 公司发了一封关于敬酒罚酒的邮件。

npm 表示我们做了一个艰难的决定,然后把 kik 封包转给 kik 公司了。

Azer “吾操汝母!”,一怒之下将自己在 npm 上的 273 个封包全部撤下,其中就包括 left-pad 封包。一石激起千层浪,依赖 left-pad 的上千个项目包括 babel 和 react-native 瞬间崩溃。大量开发者看着自己项目构建失败,顿时被吓尿。 有意思的是,社区中许多的模块都选择引入这个十一行的模块,而不是花上两分钟的时间自己去实现这个简单的字符串填充功能。

这不是npm包管理第一次出问题,也不会是最后一次。

Leftpad撤包事件、event-stream投毒事件、Ant Design彩蛋时间,使得我们不得不开始重新思考npm生态真的存在的问题,甚至去问自己:我们是不是早已忘记该如何好好地编程?

  • NPM模块粒度
  • 代码风格
  • 代码质量/效率
  • 过度依赖

对我们的启发?

  1. 依赖管理的重要性

    • 最小化依赖:尽量减少项目的依赖数量,避免引入不必要的第三方库。
    • 版本锁定:使用 package-lock.json 或 yarn.lock 文件来锁定依赖版本,确保每次安装时使用的都是相同的版本。
    • 依赖审查:定期审查项目的依赖树,了解每个依赖的作用和来源,确保它们是可信的。
  2. 供应链安全

    • 信任但验证:虽然大多数开源项目是可信的,但仍需保持警惕,特别是对于那些没有经过充分审查的小型或不活跃的项目。
    • 多源备份:考虑使用多个包管理器(如 Yarn 和 npm),并在必要时准备替代方案。
    • 镜像仓库:使用私有镜像仓库(如 Nexus、Artifactory)来缓存和管理依赖,以减少对外部服务的依赖。
  3. 社区参与

    • 贡献和维护:积极参与开源社区,贡献代码、报告问题和帮助维护项目。
    • 支持核心开发者:理解并支持开源项目的维护者,他们通常是无偿工作的,需要社区的支持和理解。
  4. 自动化测试

    • 持续集成/持续部署 (CI/CD) :建立自动化的测试和部署流程,确保在依赖更新时能够及时发现和解决问题。
    • 依赖更新策略:制定明确的依赖更新策略,定期检查和更新依赖,同时进行回归测试。
  5. 文档和沟通

    • 清晰的文档:编写清晰的文档,说明项目的依赖关系和使用方法,帮助其他开发者更好地理解和使用你的项目。
    • 沟通渠道:建立有效的沟通渠道,如 GitHub Issues、Slack 群组等,以便及时处理问题和反馈。

那我们现在怎么使用npm呢?

于是,现在我们使用 NPM 模块的正确姿势应该是这样了:

  1. 本地安装、更新需要的模块,测试、验证
  2. 执行 npm shrinkwrap 将依赖模块的版本冻结
  3. 执行 shrinkpack . 将依赖模块打包进仓库
  4. 提交代码(注意要将 npm-shrinkwrap.json 和 node_shrinkpack 一起提交哦)
  5. 发布模块或者部署应用

如果你觉得这样很繁琐,可以定义一个 NPM 命令:

 "scripts": 
 { "pack": "npm shrinkwrap & shrinkpack ." }