Everything NPM 包
一个实验性的“everything” npm 包依赖了成千上万个其他包,暴露了 npm 取消发布政策中的一个缺陷:如果有东西通过通配版本依赖了这些包,维护者实际上就无法移除自己的包。评论者争论责任更多在包作者还是 npm 的设计,尤其是对 `*` 版本的处理,以及 left-pad 事件之后形成的遗留反应。此事也重新点燃了对 JavaScript 微型依赖文化、薄弱标准库以及对语义化版本信任的更广泛担忧,并将其与 Go、Rust、Maven 等生态作比较,同时提出了 vendoring、更好的工具以及更严格的依赖规范等建议。
NPM “*” 版本规则与取消发布政策
- “*” 依赖约束加上 npm 的取消发布规则,意味着一个依赖“everything”的单个包,实际上可以阻止作者取消发布自己的包。
- 有人把这称为“bug”;也有人说这是有意为之,目的是避免版本消失时构建被破坏。
- 建议包括:
- 对
*进行更“宽松”的解释,只要至少还保留一个版本就允许取消发布。 - 软删除 / yank:对新解析隐藏版本,但仍为已有 lockfile 提供服务。
- 对取消发布请求进行人工审核,或者除恶意软件/法律原因外完全不允许取消发布。
- 对
SemVer、版本固定与可靠性
- 讨论 JS 生态中 SemVer 到底有多可信:
- 有人认为意外破坏很常见,SemVer 几乎没有意义。
- 也有人表示,大多数 minor/patch 更新都没问题;破坏很少见,并且会被视为 bug。
- 常见缓解方式:固定精确版本并手动更新,只把 SemVer 作为审查强度的信号。
- 版本固定在版本被取消发布时也无济于事,因此才引发了围绕取消发布规则的争议。
“Everything” 包的责任归属
- 观点从“鲁莽的实验/挑衅”到“揭露了 npm 设计缺陷的合法压力测试”不一而足。
- 许多人认为根本问题在于 npm 的政策,而不是这次实验;有些人觉得作者应该给出更详细的解释,也有人认为不需要更强烈的道歉。
微型包、文化与风险
- 普遍受到批评的是:极端的微依赖,以及对琐碎包的过度依赖,这会放大破坏和安全风险。
- 有人认为这是一种文化现象(“什么都去找个库”),与薄弱的标准库和历史上的浏览器怪癖有关。
- 也有人认为,开发者应该更谨慎,并为自己添加的依赖承担责任。
拟议的生态系统改进
- 更强大、更完整的标准库,以减少对小型工具包的需求。
- 对包和依赖图进行社会/质量评分,并在传递依赖激增时发出警告。
- 让复用“足够昂贵”(时间、审查),使开发者感受到每一个新依赖带来的影响。
- 更积极地进行 vendoring 或锁定依赖;Go 的模块代理、Cargo 的 yanking 和审查机制被引用为积极的模型。