跳到正文
Hacker News· jcbhmr·· 2 天前AI 评分60

vlt 创始人撰文致谢 Deno:竞争如何推动 JavaScript 生态演进

Thank You, Deno

AI 导读

vlt 创始人兼 CEO Darcy Clarke 撰文回顾 Deno 团队加入 Cloudflare、Deno runtime 将在未来一年逐步关停,JSR 继续运行在 Cloudflare 基础设施上,团队新任务是按 Cloudflare 公告把 Deno 的 celld 合并进 workerd。

正文 · AI 翻译

所有文章

开源注册表

Deno 加入 Cloudflare,并逐步结束对该运行时的投入。它的存在让我们所有人都变得更好。

2026年10月14日

Black-and-white photograph of railway tracks running toward a low sun over distant mountains

Ryan Dahl 上周宣布 Deno 团队将加入 Cloudflare。Deno 运行时将在未来一年内逐步关停,JSR 继续在 Cloudflare 的基础设施上运行,而根据 Cloudflare 的公告,该团队的新任务是将 Deno 的 celld 合并进 workerd。

这一公告发布之日,恰逢 Deno 2 发布两周年。Bun 在十个月前加入了 Anthropic。一个诱人的结论是:替代运行时的实验已经结束,Node 不战而胜。但事实上,生态系统已经获得了 Deno 所推动的那些好处,只不过不是来自 Deno 本身。

竞争对健康的生态系统至关重要

遗憾的是,Deno 在生产环境中始终未能真正达到临界规模;Node 在 2026 年的主导地位与 2018 年一样。Deno 真正做到的,是重新激活了现有霸主并对其施加压力,而这种压力并非单向流动。

Deno 最初是一次彻底决裂。Ryan 在 2018 年的 JSConf EU 上登台,列举了他会与 Node 不同的做法:默认拒绝的权限、将 TypeScript 作为一等输入、服务器上的 Web 标准 API、仅使用 ES 模块、单一可执行文件。而且,他明确表示:没有 npm、没有 package.json、没有 node_modules。依赖就是 URL。幻灯片上写得很直白:“无需列出依赖。”

我们中许多在 npm 和 Node 上投入多年的人对最后一点持怀疑态度(不是对权限或 TypeScript,那些显然很好),并在当时就说了出来。我们以前经历过,在热链接时代,每个页面都从别人的服务器上拉取 jquery.min.js,一旦它被移动或遭到入侵就会崩溃。URL 告诉你某个东西曾经在哪里,而不是它是什么。一旦你在意你测试的字节就是你发布的字节,你就需要一个完整性哈希以及记录它的地方,于是你又重新发明了锁文件。Node TSC 的 Matteo Collina 在 2020 年表示,“另一起 left-pad 事件正在酝酿,但这一次没有‘中心实体’能够修复它。”这些怀疑有些是出于防御心理,但最终恰好被证明是对的。

Deno 1.0 于 2020 年按照最初的条款发布,然后在接下来的四年里一点一点地将其收回。先是 deps.ts 约定,用一个文件重新导出每个 URL:一个名义上不是清单的清单。然后是 lock.json,每个 URL 一个完整性哈希:一个锁文件。接着是导入映射,这样你又能写裸说明符了。Deno 自己的文档如今建议使用注册表而非 HTTPS 导入,因为它们“可能在不同文件间漂移到不同版本”并且“信任提供服务的宿主”。这些正是 2018 年的反对意见,如今被重新表述为指南。

然后 Bun 出现了。Bun 0.1 于 2022 年 7 月发布,押注的方向恰恰相反:为了速度从零重建工具链,但运行现有的 npm 包、读取 package.json,并作为 node 的直接替代品。大约六周后,Deno 发布了 “Deno 即将迎来重大变化”,宣布支持 npm: 说明符,承诺在三个月内让 80–90% 的 npm 包可用,并定下成为“最快的 JavaScript 运行时”的新目标。Deno 将这一转变归功于用户反馈;从时间点看,Bun 很可能是其中很大一部分原因。Deno 2 于 2024 年 10 月完成了这项工作,实现了与 Node 和 npm 的完全兼容。在作为 Node 生态系统的替代品推出四年后,Deno 变成了运行它的另一种方式。

那是正确的决定,同时也等于承认:生态系统不会一夜之间抛弃十多年来积累的依赖。Cloudflare 的 workerd 在 2022 年开源,出于同样的原因发展出了自己的 Node 兼容层:因为包都在那里。

Node 最终不得不做出回应。自 2018 年以来,它已内置了全局 fetch、WebSocket、Web Streams 和 Web Crypto;稳定的测试运行器和 --watch;--env-file 和单可执行文件构建;稳定的权限模型;默认开启的类型剥离;node:sqlite;以及 require(esm)。Node 的贡献者(许多是志愿者)做了倾听并做出重大改变的艰苦工作,他们值得大力赞扬,但我认为如果没有另外三个运行时率先落地其中许多想法,这一切不会在那个时间线上发生。一个成熟的开放源码项目很少缺少好点子。它缺少的是紧迫感,而竞争者提供了这种紧迫感。

标准方面的工作也源于同样的压力:WinterCG 于 2022 年成立,因为多个严肃的运行时让“最小公共 API 是什么?”成为一个实际问题,而如今作为 Ecma TC55,它应该会比接下来整合的任何运行时都更长久。

包管理器与注册表

在其历史的大部分时间里,JavaScript 包生态系统是一种单一文化:一个客户端、一个注册表,以及一份非正式到在长达十五年里实际上没有文档的 API 契约。此后几乎每一项改进都来自某个拒绝接受现状的人。

Yarn(2016)坚持安装必须是确定性的,并为我们带来了锁文件、工作区和离线缓存;npm 5 在第二年推出了 package-lock.json。pnpm 证明了 node_modules 不必是数百兆字节的重复文件。Bun 让 install 快到现有工具不得不重新审视自己的性能。Deno 主张你应该能在采用一个依赖之前阅读它的源码,虽然 URL 导入没有延续下来,但这个理念延续了下来。

最近最明显的例子是安装脚本。pnpm 和 Bun 已默认不再运行它们;vlt 则从未运行过。我在 npm 工作期间,这个论点一直在内部被提出,却始终未能成为默认行为。今年六月,在一连串供应链蠕虫事件之后,GitHub 宣布 npm 12 也将默认不再运行它们。这些年间,这个想法本身没有任何变化;只是有足够多的其他包管理器已经采用了它,npm 再也无法将其视为激进之举。这种压力也是双向的:我们从 pnpm 借用了 catalogs,而 pnpm 的 namedRegistries 则借用了我们的命名注册表别名。

在注册表方面,JSR 值得称赞。它押注的方向与我们不同:发布 TypeScript 源码、要求使用 ESM、从代码生成文档。我们对其中部分做法并不认同,但还是在 vlt 中加入了 jsr: 支持,因为用户有需求。它能在关停中存活下来,是因为据我所知,它的运行成本很低,API 有文档,而且 Cloudflare 有理由让它继续存在。

现在有什么变化

两个最受欢迎、独立且由风险投资支持的 JavaScript 运行时,如今都归属于主营业务并非运行时的公司。Jarred Sumner 表示,Bun 团队与 Claude Code 团队的关系“可能看起来类似于 Google Chrome 与 V8 之间的关系”,但拥有更多独立性,而 Cloudflare 的公告也明确表示 workerd 的路线图由 Cloudflare 决定。JavaScriptCore 和 V8 一直以来就是这样获得资金的,但这仍然是一种变化。

Deno 运行时是否会出现社区分支,将告诉我们这个生态系统是否足够重视一个默认安全、标准优先的运行时,以至于愿意为一个不依附于云服务的版本付费。而 celld 并入 workerd,则是在一个一直鲜有选择的层面上提供了新的可选性:一个可自托管、开放的 Workers 与 Durable Objects 实现,由 Ryan 和 Bert Belder 领导。

JavaScript 几乎在每一层都有保险:三个生产级引擎、多个运行时、多个包管理器。当某一层发生整合时——正如运行时层现在正在发生的那样——其他层会稳住。使这一切成为可能的频繁变动,也正是人们抱怨最多的地方。“JavaScript 疲劳”已经当了十年的老梗:每周一个新框架,每月一个新打包器,还有又一个包管理器——是的,我知道我也在其中出了一份力。但没有人必须离开 Node 才能获得 fetch、权限模型或无需构建步骤的 TypeScript,如今也没有人必须更换包管理器才能让安装脚本默认关闭。这些东西出现在人们已经在使用的工具中,是因为别人先发布了它们,而现有者不得不做出回应。这些项目并不总能胜出,但这些想法通常都能胜出,而最终用户无论如何都从中受益。

致 Ryan、Bert、Bartek 以及 Deno 团队的其他成员(无论过去还是现在):你们的共同努力丰富了我们的共享生态系统。谢谢你们!

Darcy Clarke
创始人兼 CEO,vlt

来源:Hacker News · vlt.io