我和Deno的友谊结束了,现在Node是我最好的朋友
摘要
开发者 David Bushell 解释了他为何放弃 Deno 转而使用 Node.js,内容涉及使用 PNPM 进行包管理、Node 对 TypeScript 类型剥离的限制,以及迁移他的静态网站生成器。
<p><a href="https://lobste.rs/s/a9kwzv/friendship_ended_with_deno_now_node_is_my">评论</a></p>
查看缓存全文
缓存时间:
2026/10/05 11:11
# 与 Deno 的友谊走到了尽头,如今 Node 才是我的好兄弟
Source: https://dbushell.com/2026/10/03/deno-to-node/
No AI — 由人类制作 · 2026年10月3日 星期六
终于到了我回去讨好 Node 的时候了!(https://nodejs.org/)
这个月我在一个 [SvelteKit](https://svelte.dev/) 客户端项目上重度使用 Node。Node 是什么时候变得这么强的?Deno 一直是我首选的运行时,时间久到我都忘了怎么用 Node。现在回来了,我才发现 ECMAScript† 的那些语法糖全都支持了,那些陈旧又烦人的 API 也都被替换或现代化了。最重要的是,我再也不用看到 `require()` 了。
†看来 Oracle 那场商标纠纷(https://javascript.tm/)不太可能有个好结局了 :(
## 包管理
[官方 Node 文档](https://nodejs.org/en/download)推荐把网上的脚本直接管道给 bash 来安装 [NVM](https://github.com/nvm-sh/nvm)(用来管理 Node 和 NPM)——我们永远学不乖。我和 NVM、NPM 那点(陈年)打交道的经历可谈不上愉快。我听说 [Fast Node Manager(FNM)](https://github.com/schniz/fnm)切换 Node 版本更好用。我平时当然用最新版,但客户的项目要求稳定,所以……
我也选用了 [PNPM](https://pnpm.io/),免得*立刻*就中招。(NPM 里的那个 “M” 代表 “malware”。)有些我用的脚本把二进制名称硬编码死了,于是我加了两个别名:
```
alias npm=pnpm
alias npx=pnpx
```
这大概是犯罪,但到目前为止运行得毫无破绽。
PNPM 还会拦截 post-install 脚本。NPM 现在还放任这些脚本随意执行吗?
我还往 `pnpm-workspace.yaml` 里加了额外的设置,用来延缓恶意软件的更新。
```
minimumReleaseAge: 1440
trustPolicy: no-downgrade
```
起初我试着把最短发布时长设成 “一个月”,因为微软至少需要这么长时间才能下架被举报的恶意软件。但这导致了依赖问题——PNPM 怎么都匹配不出合适的版本。最后我折中为 “一天”;够长了,可以让别的倒霉蛋先当小白鼠,替我测试下一个 Shai-Hulud。
## TypeScript
Node 现在可以运行 TypeScript 了,不会像个小婴儿那样,只要星位不对就大发脾气。话虽如此,把 TypeScript 包直接发布到 NPM 也不是随便就能做到的事。
```
error: [ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING]:
Stripping types is currently unsupported for files under node_modules
```
为什么?把类型剥掉不就行了,老兄,我知道你行的!让我跟魔鬼签个契约吧!
> 为了劝阻包作者发布用 TypeScript 编写的包,Node.js 会拒绝处理 `node_modules` 路径下文件夹中的 TypeScript 文件。—— [Node.js v26.10.0 文档](https://nodejs.org/docs/latest-v26.x/api/typescript.html#type-stripping-in-dependencies)
这个限制是理念上的,而不是技术上的。不过我能理解。TypeScript 是微软的产品。一旦开了这个闸门,整个生态系统都会被污染。没人想再多一些微软。我倒是很想在 ECMAScript 里看到轻量的 “原生类型”。目前确实有[类型注解提案](https://tc39.es/proposal-type-annotations/)。我怀疑那些东西修成正果之前,我就已经退休了。
没有 TypeScript 包,我就得找最新的那套 churnware 垃圾工具来打包我的东西。[Tsdown](https://tsdown.dev/) 搞定了这件事,代价是多了两个点文件。对此我不太高兴(每个点文件都代表一个错误)。不过想想我删掉 `deno.json` 之类的文件,应该也算扯平了吧。
说到微软锁定,因为他们[把 GitHub 毁了](https://dbushell.com/2026/04/29/github-is-sinking/),我现在自建了一个 [Forgejo 实例](https://git.dbushell.com/)。而 [NPM 的种种限制](https://docs.npmjs.com/generating-provenance-statements#provenance-limitations)意味着我的包失去了 “provenance(来源证明)”。我不得不配置 [PNPM 的信任策略](https://pnpm.io/settings/dependency-resolution#trustpolicyexclude),允许使用我自己的东西。真是欢乐时光啊!
## 迁移我的网站
我对 Node 的最终测试,是把我那个[静态站点生成器](https://dbushell.com/2025/05/11/the-static-site-churns/)从 Deno 迁移过来。就在几个 Node 版本之前,这还是个需要大改造的活儿。而今天,在 `Node v26.10.0` 上,我发现自己几乎没干什么活。
唯一必须做的改动,是把 Deno 的文件系统 API 替换成 `node:fs`——它比我记忆中(大约 10 年前)的样子改进太多了。除此之外,我只需要把 `Deno.serve` 换成 Hono 的 node 适配器(https://hono.dev/docs/getting-started/nodejs)(也就是对 `node:http` 的一层封装)。
这次最小化迁移之后,我震惊地发现**构建速度提升了 15%**。我的代码库仍然沿用着地道的 Deno 风格。我敢说,因为没有用上其他内置的 Node API,我白白浪费掉了一些性能。这留待以后探索。我另外做的唯一改动,是把 Deno 的 `@std/path` 换成了 `node:path`,纯粹就是改一下 import。
所以如果现在要我做个 TL;DR:Node 玩了波大变身,哇哦!
你们大概早就知道了。我一直用 Deno,不过是出于习惯和熟悉。而且最近我对写服务端 JavaScript 也提不起多少兴趣。
## Deno 的衰落
我把这部分埋在下面,因为再讲就是鞭打一匹死马了。归根结底,Deno 毁在了他们让硅谷马戏团来定义 “成功” 上。Deno 从一个富有创新性的现代 JavaScript 运行时,沦落成了一家产品毫无吸引力(https://dbushell.com/2025/04/28/denos-decline/)的无聊初创公司。一半的员工被裁,剩下的那些人成天发推文幻想 AI、用 vibe-coding 拼凑一个 “Temu 版 Cloudflare”。
如今没有任何理由再去用 Deno 运行时。*Deno Land Inc.* 几年前就已经停止创新了。Node 虽然慢,但一直在稳步追上,甚至在某些地方已经超过了 Deno。
最终把我推走的是:
- ZSH 集成连续几周都是坏的
- JSR 激进的 “429(请求过于频繁)”
- 有 Bug 让 Deno 在处理并发 HTTP 请求时直接卡死
基本上就是那些让它在我本就一堆批评之上、变得几乎不可用的东西。JSR 的支持人员响应很快,我一申请就把我的账号删了。我不喜欢在互联网上留下一堆死掉的账号。我的包全都看不见了,但旧版本依然可以安装。
早期确实挺有意思的,但现在是时候说再见了。
```
brew uninstall deno
```
相似文章
Lobsters Hottest
一篇反思性文章,批评 Deno 转向与 Node.js 兼容的做法,认为这削弱了其原本简洁、零配置的理念,而正是这些特点让开发者对其青睐有加。
Hacker News Top
Deno 正加入 Cloudflare,并逐步缩减对其运行时的投入;与此同时,JSR 将继续在 Cloudflare 的基础设施上运行,团队也将把 celld 合并到 workerd 中。文章回顾了 Deno 带来的竞争如何推动 Node/npm 生态系统的改进,尽管 Deno 自身始终未能形成足够的用户规模。
X AI KOLs Timeline
Cloudflare 正在吸纳 Deno 核心团队成员,包括 Ryan Dahl 以及 Bartek Iwańczuk 的同事,以将 workerd 打造为一流的、可自托管的开源 JavaScript 运行时,这标志着 JavaScript 运行时格局的一次显著转变。
Simon Willison's Blog
Cloudflare 正在收购 Deno,基于其 celld 项目进行构建,并将 workerd 的自托管作为一等功能;而 Deno 运行时在此后一年内只会获得错误修复,随后开发将终止。Deno 和 Node.js 的创造者 Ryan Dahl 认可了这一决定,他表示 Deno 已被 Node 兼容性所拖累,而他希望专注于 celld 这类基于对象存储的服务器模型等新抽象。
Hacker News Top
Deno 2.9 引入了 `deno desktop`,用于使用 Web 技术构建原生桌面应用程序,同时改进了 Node.js 兼容性、CSS 模块导入和更快的启动速度。