要点
观察一篇 Deno。定位一句话说完:Rust 写的 JavaScript/TypeScript 运行时,卖点从来是安全默认加一体化工具链,而 Deno 2(2024 年 10 月 9 日 GA)补上了它此前最大的短板——与 Node/npm 生态的兼容。截至本文(2025 年 10 月),稳定线是 Deno 2.5.x(2025 年 9 月 10 日发布,官方标定的 LTS 长期支持线)。看完这篇你能回答四个问题:Deno 2 的”兼容 Node”具体兼容到什么程度、权限模型日常怎么用、它和 Node/Bun 三方各自站在什么位置、以及现在该不该把项目挪过去。
Deno 2 的关键变化:Node 生态成为一等公民
Deno 1.x 时代最大的尴尬不是技术,是孤岛:包要挂它自己的注册表体系,npm 生态的存量代码搬不动,”下一个 Node”喊了几年,多数团队看一眼就走。Deno 2 的路线调整很彻底——不再试图替代 Node,而是直接住进 Node 生态:
项目里有 package.json,Deno 就按 Node 的规矩来:识别它、默认使用 node_modules 目录、支持 npm workspaces;跑代码时原生支持 npm:、node:、jsr: 三种模块标识符;Node 项目不用改一行,把 node 命令换成 deno 大概率能直接跑。Node 的核心设施也有对应物——流用的是标准 Web Streams API,多线程用 Web Worker,机制上和站内Node.js 流与 Worker讲的是同一套概念,只是 API 对齐了 Web 标准。
# 对已有 Node/npm 项目的三种姿势
deno run -A npm:vite dev # 直接跑 npm 包,不用先 npm install
deno add npm:express # 有 package.json 的项目:写进它并装到 node_modules
deno run -A main.js # 既有项目把 node 换成 deno,直接跑
1. 没有 package.json 的独立脚本,npm 包同样即取即用
兼容也不是百分之百:原生插件(node-gyp 一类)、少数依赖 Node 内部 API 的包仍可能出问题,动手前以官方兼容性文档为准,别拿核心业务当试验田。
上手:deno run 与权限模型
最小说明问题的例子,单文件直接跑:
// server.ts —— 没有 package.json,没有 tsconfig,也没有编译步骤
Deno.serve({ port: 8000 }, (req) => {
const url = new URL(req.url);
if (url.pathname === "/health") return new Response("ok");
return new Response(`hello deno, path=${url.pathname}`);
});
deno run --allow-net server.ts # 显式授出"监听网络"这一项权限
权限模型(permission model)是 Deno 区别于 Node 的根本差异:默认拒绝一切敏感能力,读写文件、访问网络、读环境变量都要显式授权。Node 里一段被投毒的依赖可以静默读走你的 .env 并外传——这在 Deno 默认配置下跑不通,因为进程压根没有这两项权限。常用标志:
| 权限标志 | 开放的能力 | 典型场景 |
|---|---|---|
| –allow-net=api.example.com | 网络访问,可限定域名与端口 | 调外部 API、起服务监听 |
| –allow-read=./data | 读文件系统,可限定目录 | 读配置、读静态资源 |
| –allow-write=./tmp | 写文件系统,可限定目录 | 写日志、写构建产物 |
| –allow-env | 读取环境变量 | 注入配置 |
| -A | 以上全部 | 本地一次性脚本,别带上生产 |
反模式点名:日常一律 -A。权限模型是 Deno 的核心卖点,-A 等于亲手把它关掉,剩下的是一个速度未必更快、生态肯定更小的 Node。正确姿势是把最小权限写进 deno.json 的任务定义里,2.5 起还能用 permission sets 把常用权限组集中声明、按任务复用——授权一次,全队受控。
一体化工具链与 TS 原生
TypeScript 直接运行,没有编译步骤——这对从 Node 过来的人是体感最强的差异:不用配 ts-node、不用关心构建产物与源码的映射。deno fmt、deno lint、deno test、deno task 全部内置于单一可执行文件,格式化、静态检查、测试、任务运行开箱即用;deno compile 还能把脚本打成单个可执行文件发给别人。语言层面没有任何私有扩展,跑的就是标准 JS/TS——对语言特性本身想系统补课的,站内Node.js 与 JavaScript 语言特性详解通用于两个运行时。工具链层面的这些能力,此前是 Node 要靠 Prettier、ESLint、Vitest 各自拼装出来的。
与 Node/Bun 的一句话定位
三个运行时常被放在一起比,但各自的优先级不同:
| 维度 | Node.js | Bun | Deno 2 |
|---|---|---|---|
| 一句话定位 | 生态默认项,库最全、人最好招 | 主打性能与启动速度,工具链一体化 | 安全默认,工具链一体化,TS 原生 |
| npm 生态 | 原生 | 原生(兼容大多数包) | 2.0 起官方兼容,仍有边角 |
| TypeScript | 靠工具链,新版本逐步原生支持 | 原生直接跑 | 原生直接跑,零配置 |
| 权限模型 | 无,进程能力全开 | 无,进程能力全开 | 默认沙箱,显式授权 |
| 适合谁 | 团队协作、求稳、生态优先 | 追运行速度的工具型项目 | 脚本、CLI、安全敏感的边缘服务 |
选型逻辑一句话:拿不准就用 Node——它仍是招聘市场、教程资料、三方库适配的默认答案;Bun 和 Deno 都要用”它多给了我什么”来说服自己。
要不要现在用它
诚实的判断:存量大型 Node 项目没有迁移的必要——Deno 2 的兼容换来的是”能跑”,而迁移的收益(权限模型、一体化工具链)不足以覆盖回归验证的成本。值得上 Deno 的场景是那些本来就不值得配一整套 Node 工具链的东西:内部小工具、CLI 脚本、爬虫、边缘函数——单文件、原生 TS、内置测试,写完即用。安全敏感的服务(处理不可信输入的解析器、对外暴露的边缘接口)是它独有的加分项,权限模型在 Node 侧没有等价物。至于”新项目要不要 All in Deno”,2025 年 10 月这个时点的答案是:团队项目再等等,个人项目随意——它已经是一个能干活的运行时,只是生态重心仍在 Node 那边。
延伸阅读
想在 Node 侧先把 Web 服务的基础概念打牢,从站内Fastify 入门开始,路由、插件、schema 校验这些概念在 Deno 生态里同样适用;运行时差异看本篇即可,语言层面的进阶补课见上文的 JavaScript 语言特性详解。
版本核实(以官方文档为准):Deno 2.0 发布于 2024-10-09(官方博客 Announcing Deno 2),核心变化为 package.json/node_modules/npm workspaces 兼容与 npm:/jsr: 标识符;Deno 2.1(2024-11)起引入 LTS 长期支持通道;截至本文稳定线为 2.5.x(2025-09-10 发布,标定 LTS,新增 deno.json permission sets,内置 V8 14.0 与 TypeScript 5.9.2)。安装命令均不钉版本号,以 docs.deno.com 当前文档为准。