🦕 Deno
一句话定性
2020 年,Ryan Dahl 站到台上,列出他对 Node.js 的十个遗憾,然后说:“所以我做了 Deno。” 这是技术史上罕见的一幕——原作者亲手否定自己最成功的作品,从零重写一个”如果当年知道现在所知,会怎么做”的运行时。
一、它是什么 & 出现的时代
Deno 是一个基于 V8、用 Rust 编写的 JavaScript / TypeScript 运行时,2020 年由 Node.js 之父 Ryan Dahl 发布(1.0 版)。
它的起点是 Dahl 2018 年在 JSConf EU 的著名演讲 《10 Things I Regret About Node.js》(我对 Node 的十个遗憾)。Deno 就是这场演讲的”工程化答案”。
Deno 名字的由来
Deno = De + No(de),把 “node” 的字母重排。它的吉祥物是只恐龙(dino),致敬 JS 的”史前”气质。
二、为什么会出现(解决上一代什么痛点)
Ryan Dahl 列出的”十个遗憾”(节选最关键的几条),每一条都直接对应 Deno 的一个设计:
| Node 的遗憾 | Deno 的修正 |
|---|---|
| 没坚持用 Promise(导致回调地狱) | 全面 async/await + Web 标准 API |
| 安全模型缺失(脚本默认全权限) | 默认沙箱,文件/网络/环境需显式授权 |
| 构建系统(GYP)选错了 | 用 Rust + 标准工具,无 node-gyp |
package.json / node_modules 设计臃肿 | 去掉两者,改用 URL 导入 + 全局缓存 |
| 模块解析太复杂(隐式扩展名、index.js) | 显式、像浏览器一样的 ES-Modules |
| 没有原生 TypeScript | 原生执行 TS,无需配置 |
核心矛盾
Node 诞生于 2009,当时 Promise/ESM/TS 都还不成熟,很多决策是”时代的妥协”。十年后这些妥协变成了包袱——而 Dahl 想要一张白纸,直接采用今天的 Web 标准。
三、核心机制 & 为什么流行
1. 默认安全(Secure by Default)
Deno 脚本默认跑在沙箱里,不能读文件、不能联网、不能读环境变量,除非你显式授权:
deno run app.ts # 啥都不能干
deno run --allow-net app.ts # 只允许联网
deno run --allow-read=./data app.ts # 只允许读 ./data
这直接针对 Node 的供应链攻击温床——一个恶意依赖再也不能”装上就偷你的密钥”。
2. 原生 TypeScript
deno run app.ts 直接跑,不需要 tsc、不需要 ts-node、不需要配置。TS 是一等公民。
3. Web 标准 API
fetch、Request、Response、URL、Web Crypto、Worker……Deno 直接复用浏览器里你已经会的 API,而不是 Node 那套自创的 http/Buffer。理念:浏览器和服务端不该是两套知识。
4. URL 导入 + 去 node_modules
import { serve } from "https://deno.land/std/http/server.ts";模块直接从 URL 引入,首次下载后缓存到全局——没有 node_modules、没有 package.json(早期理念)。像浏览器一样去中心化。
一体化工具
Deno 内置 formatter(
deno fmt)、linter(deno lint)、test runner(deno test)、打包、文档生成——开箱即用,无需拼装工具链。这点后来被 Bun 进一步发扬。
四、带来的新问题 / 副作用
理想主义撞上生态惯性
- 生态不兼容是致命伤:早期 Deno 拒绝 npm /
node_modules,意味着几十万个 npm 包用不了。开发者无法迁移,推广严重受阻。这是 Deno 最大的战略失误——低估了生态惯性(二阶效应)。- URL 导入的隐患:依赖散落在各种 URL,版本管理、安全审计、离线可用性都成问题,后来不得不引入
deno.json和 import maps 来收敛。- “更好的设计”未必赢:Deno 几乎每个技术决策都比 Node 更”正确”,但正确 ≠ 流行。VHS 战胜 Betamax 的故事在重演。
五、现状 / 演化
- Deno 2(2024)的战略转向:全面拥抱 npm 兼容和
package.json,从”Node 杀手”改口为”更好的 Node 开发体验”。这是对生态惯性的低头,也是务实的胜利。 - 主打场景:边缘计算(Deno Deploy)、一体化开发体验、安全敏感场景。
- 推出 JSR(JavaScript Registry),一个面向 ESM/TS 的现代包仓库,挑战 npm。
- 它的很多理念已被”反向移植”回 Node.js(原生 ESM、内置 test、
--strip-types)——即使 Deno 没赢,它的思想也赢了。
六、对后续技术的影响(因果链)
Node.js 的"十个遗憾"(Ryan Dahl 自我反思)
│
▼
Deno(2020, Rust)
│
┌───────────────────┼─────────────────────┬──────────────────┐
▼ ▼ ▼ ▼
默认安全沙箱 原生 [[TypeScript]] Web 标准 API 去 node_modules
│ │ │ (URL 导入)
│ │ │ │
│ ▼ ▼ ▼
│ 倒逼 Node 补 --strip-types 推动 WinterCG 生态惯性反噬
│ (运行时标准对齐) │
▼ ▼
影响 [[Bun]] 也走"安全/标准/一体化"路线 Deno 2 妥协,转向 npm 兼容
历史地位
Deno 是一封写给整个 JS 生态的”检讨信 + 提案书”。它在商业上没能颠覆 Node.js,却在思想上重塑了所有运行时——默认安全、原生 TS、Web 标准对齐,如今都成了行业共识。它证明了一件事:有时候推动进步的不是取代王者,而是逼王者变得更好。
🔗 相关:JS运行时演进史 | Node.js | Bun | TypeScript | ES-Modules | Chrome | npm-Yarn-pnpm-包管理