出处:掘金
原作者:四叶草会开花
背景
作为 mockm 项目的维护者,这几天我一直在优化 CI/CD 流水线。终于把自动化测试和发布流程都搞定了,心想着可以安心写代码了。结果今天早上一看 GitHub Actions,我傻眼了…
项目突然构建失败了:
昨天还好好的 CI/CD 流水线,今天突然就红了一片!
第一反应:又是我的配置问题?
点开失败的 job 详情,看到 build-and-release
这一步挂了。心想肯定又是我的 docker-compose
配置有问题,或者是某个环境变量没设对
毕竟刚优化完 CI/CD,出问题很正常嘛…
但是当我仔细查看错误日志时,发现了一个让我摸不着头脑的错误:
npm ERR! 404 'stylus@https://registry.npmjs.org/stylus/-/stylus-0.64.0.tgz' is not in this registry
stylus
包不存在?什么鬼?
我重新运行了一遍 workflow,还是同样的错误。然后我在本地试了试 npm install
,结果更震惊了 —— NPM 告诉我这个用了好几年的 CSS 预处理器库,突然从地球上消失了
这时候我才意识到,不是我的 CI/CD 配置的问题,而是整个 NPM 生态出大问题了
直到我打开 Twitter,看到满屏的哀嚎,才意识到这不是我一个人的问题。这是一场全球性的前端灾难
全球前端开发者陷入恐慌
这让我想起了 2016 年的 left-pad
事件,但这次更严重。left-pad
至少只是一个小工具函数,而 Stylus 是整个 CSS 预处理生态的重要组成部分
我开始担心:不光是我的项目发布不了,全世界有多少个项目的 CI/CD 都在今天红屏了?有多少开发者像我一样,以为是自己的配置问题,结果查了半天发现是外部依赖炸了?
left-pad
事件
left-pad
是一个由 Javascript 程序员 Azer 编写的 NPM 包,功能是为字符串添加左侧填充,代码仅有 11 行,但却被上千个项目使用,其中包括著名的 babel 和 react-native 等Azer 收到 kik 公司的邮件,对方称要发布名为 kik 的封包,但 kik 这个名字已被 Azer 占用,希望他能改名。Azer 拒绝后,kik 公司多次与他沟通无果,便向 NPM 公司发邮件。最终,NPM 公司将 kik 封包转给了 kik 公司
Azer 因 NPM 公司的这一决定感到愤怒,一怒之下将自己在 NPM 上的 273 个封包全部撤下,其中包括
left-pad
封包。这导致依赖left-pad
的成千上万个项目瞬间崩溃,大量开发者的项目构建失败
GitHub Issues 爆炸式增长
短短几小时内,与 Stylus 相关的错误报告如雨后春笋般涌现:
- Nx 框架:
'stylus@ https://registry.npmjs.org/stylus/-/stylus-0.64.0.tgz' is not in this registry on npm install nrwl/nx #32031
- TypeScript CSS Modules:
Stylus contained malicious code and was removed from the registry by the npm security team mrmckeb/typescript-plugin-css-modules#287
- ShadCN Vue:
ERR_PNPM_NO_MATCHING_VERSION due to yanked package unovue/shadcn-vue #1344
社交媒体上的恐慌
Twitter、Reddit、Discord 等平台上充斥着开发者的求助和抱怨:
“我的整个项目都跑不起来了,Stylus 到底发生了什么?”
“生产环境部署失败,老板在催进度,Stylus 你什么时候能回来?”
“这是我见过最离谱的 NPM 事故,一个 CSS 预处理器居然能让半个前端圈瘫痪”
然后我发现了最荒谬的真相…
花了一个上午收集信息后,我发现了这个让人哭笑不得的真相:
NPM 把 CSS 预处理器和 ChromeOS 的触控笔搞混了!
没错,你没看错。导致 Stylus 被封禁的 CVE-2025-6044,说的是 ChromeOS 设备上的物理触控笔存在安全漏洞。而 NPM 的安全团队,可能是用了某种自动化工具,看到”Stylus”这个名字,就把我们前端开发者天天用的 CSS 预处理器给 ban 了。
我第一次看到这个解释的时候,真的以为是在看洋葱新闻。
让我们来对比一下这个绝世乌龙:
真正有漏洞的”Stylus”:
- ChromeOS 设备上的物理触控笔工具
- 需要物理接触设备才能攻击
- 和前端开发一毛钱关系都没有
被误杀的”stylus”:
- 前端开发者的 CSS 预处理器
- 纯软件库,连 UI 都没有
- 被全世界几百万项目依赖
这就好比因为苹果公司出了安全问题,就把超市里的苹果都下架了一样荒谬!
我为这个维护者感到心疼
看到 Stylus 维护者 @iChenLei 在 GitHub 上的无助求助,说实话我挺心疼的。
作为一个也维护过开源项目的人,我太能理解那种感受了:你辛辛苦苦维护了这么多年的项目,服务了全球这么多开发者,结果因为一个莫名其妙的错误就被封禁,而且申诉无门。
他在 Issue 里写道:
“这影响了很多人。虽然这不是我的错,但我向每个人道歉。”
这句话让我特别感动,明明是 NPM 搞错了,但他还是在为用户的困扰道歉,这就是开源维护者的责任感。
而且你看他做的这些努力:
- 立即提交官方 ticket
- 在 Twitter 上求助
- 甚至还展示了自己的 2FA 截图证明账户安全
但 NPM 官方到现在还没有任何回应。这让我想起那句话:“开源开发者用爱发电,平台方用AI管理”
临时解决方案:前端社区的自救行动
面对官方的无回应,社区开始了自救。说实话,这种时候最能看出开源社区的凝聚力。
我试过的几种方法
方法一:直接用 GitHub 源
npm install https://github.com/stylus/stylus/archive/refs/tags/0.64.0.tar.gz
这个方法管用,但感觉不太优雅。而且每次安装都要下载整个 repo,速度慢得要命
方法二:Package.json override
{
"overrides": {
"postcss-styl>stylus": "https://github.com/stylus/stylus/archive/refs/tags/0.64.0.tar.gz"
}
}
这个比较适合已有项目,但对新项目来说还是很麻烦
方法三:换 NPM 源
npm config set registry https://registry.npmmirror.com/
试了几个国内镜像,大部分还有缓存,可以正常安装。但总感觉不是长久之计
让我感动的社区互助
在各种群和论坛里,大家都在分享解决方案,没有人在抱怨,更没有人在指责维护者。这让我想起了为什么我当初会爱上开源社区
有个老哥甚至建议大家去转发维护者的 Twitter 求助,我觉得这个主意不错。毕竟有时候社交媒体的影响力比正式渠道还管用
这件事让我重新思考了很多问题
说实话,这次事件让我开始重新审视我们前端开发的生态
NPM 真的靠谱吗?
作为一个在前端圈混了这么多年的老司机,我一直觉得 NPM 已经足够成熟稳定了。但这次事件让我意识到,我们可能过于依赖这个中心化的平台了
想想看:
- 一个错误的安全判断,就能让全球项目停摆
- 维护者申诉无门,只能在社交媒体求助
- 没有任何预警机制,用户只能被动承受
这真的合理吗?
开源维护者太难了
@iChenLei 的遭遇让我想起了很多开源维护者的心酸。他们用爱发电,服务全世界,但遇到问题时却如此无助
我觉得我们作为受益者,应该:
- 多给开源项目捐赠
- 积极参与社区建设
- 在这种时候给维护者更多支持
而不是只会在出问题时抱怨
前端生态的脆弱性
这次事件也暴露了现代前端开发的一个问题:我们的依赖树太复杂了
一个简单的项目,动不动就有几百个依赖。每个依赖都是一个潜在的故障点。虽然这种模块化的开发方式很高效,但风险也确实不小
我开始思考:
- 是不是应该减少一些不必要的依赖?
- 关键依赖是不是应该做备份?
- 公司是不是应该建立私有 NPM 镜像?
从 left-pad 到 stylus,我们学到了什么?
2016 年的 left-pad
事件,曾经让整个 JavaScript 生态停摆了一天。当时大家说要吸取教训,要建立更稳定的包管理机制
现在 2025 年了,类似的事情又发生了,而且更严重
这让我意识到,单纯依靠技术手段可能解决不了根本问题。我们需要的是:
- 更透明的治理机制:NPM 的决策过程应该更开放
- 更快速的申诉渠道:不能让维护者只能在 Twitter 求助
- 更多元化的生态:不能把鸡蛋都放在一个篮子里
我的一些建议
作为一个用户,我觉得我们可以:
短期内:
- 建立项目的依赖备份机制
- 使用多个注册表镜像
- 关键项目使用
package-lock.json
长期来看:
- 支持去中心化的包管理方案
- 推动 NPM 改进治理机制
- 给开源项目更多的资金和技术支持
资金支持?之前为了让 mockm 项目的文档能让网络“不方便”的大家也能快速访问,自己花钱买的域名、服务器。但是这么多年工资也没有涨,可能是我没有好好工作。撑不下去了(本来好像也没几个用户),所以我打算把文档部署在 GITHUB PAGE 上了,网络不方便?爱谁谁!
写在最后
这次事件提醒我们,我们的工作比想象中更脆弱。但也让我看到了社区的力量:当官方渠道失效时,我们依然能够相互帮助,共度难关。PS:这就是为什么我爱这个行业的原因
然而一个又产生一个新想法:一个小小的名称混淆,就能让全球的前端开发陷入混乱。那么,“软件正在吞噬世界,但谁来守护软件?”