1055 字
5 分钟
Deno 上手体验:一些好用的地方和需要注意的点
2025-10-27

我最近在试用 Deno,就是那个 Node 开发者为 JS 弄的新运行时。

总的来说,Deno 是一个很有意思的运行时,它在很多地方简化了开发流程,但也带来了一些新的概念和需要注意的地方。我会把我遇到的几个关键点列出来,包括一些好用的地方和几个比较“坑”的体验,给大家一个参考,如果以后有项目要用,可以少走点弯路。

1. 内置功能很方便,能大量减少模板代码#

这是我上手 Deno 后感觉最舒服的一点,在 Node 里,我习惯了做什么事都先 pnpm install,起码要把基础功能的包给安装上,但 Deno 把很多常用功能直接内置到了全局的 Deno 对象里。

举两个例子:

  • Web 服务器:想启动一个 HTTP 服务,直接用 Deno.serve 就行了。
    // main.ts
    Deno.serve((_req) => new Response("Hello, World!"));
    一行代码搞定,不需要安装 Express 或其他框架。
  • 键值对数据库:Deno 内置了一个开箱即用的 KV 数据库 Deno.Kv。 对于一些需要轻量级数据持久化的小项目或原型,这个功能非常实用,省去了配置和连接外部数据库的步骤。

2. 生态兼容性:JSR、NPM 和 Node API#

Deno 在努力兼容 Node 生态,但这里有几个点需要注意:

  • Node 内置库不完全兼容:我一开始以为 Deno 能无缝使用 Node 的所有内置库(比如 fs, path),实际上,它只兼容了一部分,使用时需要加上 node: 前缀,比如 import fs from "node:fs"。具体哪些 API 兼容,需要去查官方文档,不能想当然。
  • JSR 和 NPM 是两回事:JSR 是 Deno 官方的包注册表,而 NPM 是 Node 的。虽然 Deno 支持通过 npm: 前缀直接安装和使用 NPM 包(比如 import express from "npm:express"),但这并不意味着所有包都能正常工作,如果一个 NPM 包依赖了某个 Deno 未兼容的 Node API,运行时还是会报错。

3. 核心设计:强大的安全沙箱(以及它带来的大坑)#

Deno 的一个核心理念是“默认安全”,你的代码在没有显式授权的情况下,什么都干不了,比如不能读写文件,不能访问网络,也不能读取环境变量。

与其说它是个运行时,不如说它更像一个沙箱,你需要通过命令行标志来给程序授权(写在 deno.jsonc 中也行):

  • --allow-read:允许读取文件
  • --allow-net:允许访问网络
  • --allow-write:允许写入文件
  • …其他的需要查看文档

这个设计理念本身没有问题,能有效控制代码权限,防止潜在的安全风险,问题出在他的默认行为上,让我踩了大坑。

我的程序里有一段很简单的 fetch 网络请求代码,每次运行时,程序跑到 fetch 那里就直接挂起了——没有报错,没有超时,没有任何提示,就是卡住不动了。

我花了很多时间去排查网络、代码逻辑,甚至怀疑是 Deno 的 bug,最后才发现,根本原因是我没有在启动命令里加上 --allow-net 来授予网络权限。

我完全能理解这种安全限制,但我无法接受这种用“静默挂起”来代替“明确报错”的默认行为。如果它能直接抛出一个 PermissionDenied 之类的错误,比起挂起,更能让用户或者开发者意识到,对于新手来说,这种体验非常糟糕。

总结#

最后总结一下:

  1. 内置 API:对于新项目,先看看 Deno 全局对象里有没有现成的功能,可以省去不少功夫
  2. 谨慎对待兼容性:不要默认所有 Node 的东西都能在 Deno 里跑,使用前最好先查一下文档
  3. 注意权限问题:如果你的程序(特别是涉及 IO、网络的部分)莫名其妙地挂起或不工作,第一反应应该是去检查标记,而不要先怀疑自己的业务逻辑
Deno 上手体验:一些好用的地方和需要注意的点
https://blog.erio.work/posts/deno上手体验分享/
作者
Dupfioire
发布于
2025-10-27
许可协议
CC BY-NC-SA 4.0