1055 字
5 分钟
Deno 上手体验:一些好用的地方和需要注意的点
我最近在试用 Deno,就是那个 Node 开发者为 JS 弄的新运行时。
总的来说,Deno 是一个很有意思的运行时,它在很多地方简化了开发流程,但也带来了一些新的概念和需要注意的地方。我会把我遇到的几个关键点列出来,包括一些好用的地方和几个比较“坑”的体验,给大家一个参考,如果以后有项目要用,可以少走点弯路。
1. 内置功能很方便,能大量减少模板代码
这是我上手 Deno 后感觉最舒服的一点,在 Node 里,我习惯了做什么事都先 pnpm install,起码要把基础功能的包给安装上,但 Deno 把很多常用功能直接内置到了全局的 Deno 对象里。
举两个例子:
- Web 服务器:想启动一个 HTTP 服务,直接用
Deno.serve就行了。
一行代码搞定,不需要安装 Express 或其他框架。// main.ts Deno.serve((_req) => new Response("Hello, World!")); - 键值对数据库: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 之类的错误,比起挂起,更能让用户或者开发者意识到,对于新手来说,这种体验非常糟糕。
总结
最后总结一下:
- 内置 API:对于新项目,先看看
Deno全局对象里有没有现成的功能,可以省去不少功夫 - 谨慎对待兼容性:不要默认所有 Node 的东西都能在 Deno 里跑,使用前最好先查一下文档
- 注意权限问题:如果你的程序(特别是涉及 IO、网络的部分)莫名其妙地挂起或不工作,第一反应应该是去检查标记,而不要先怀疑自己的业务逻辑
Deno 上手体验:一些好用的地方和需要注意的点
https://blog.erio.work/posts/deno上手体验分享/
