Deno 2.8 实测:6 个新命令 + Node 兼容性飙到 76%,它想干掉 npm

Deno 2.8 实测:6 个新命令 + Node 兼容性飙到 76%,它想干掉 npm

上周四 Deno 2.8 发布了。我花了两天时间把新功能全跑了一遍,说说实际感受。

先说结论

这个版本最值得关注的不是某个单一功能,是整体的工具链补全。6 个新子命令(deno audit fixdeno cideno packdeno transpiledeno bump-versiondeno why),加上 CLI 默认识别 npm 包名、Node.js 测试套件通过率从 42% 涨到 76.4%------加在一起看,Deno 在包管理器这个方向上已经补齐了 npm/yarn/pnpm 的大部分能力。

deno audit fix:自动修漏洞

2.6 版本加了 deno audit,能扫描 npm 依赖的已知漏洞。2.8 多了个 fix,直接帮你升级到补丁版本。

bash 复制代码
$ deno audit fix

╭ body-parser vulnerable to denial of service when url encoding is enabled
│ Severity: high
│ Package: body-parser
│ Vulnerable: <1.20.3
╰ Info: https://github.com/advisories/GHSA-qwcr-r2fm-qrc7

Found 2 vulnerabilities
Severity: 0 low, 1 moderate, 1 high, 0 critical

Fixed 1 vulnerability:
 body-parser 1.19.0 -> 1.20.3

1 vulnerability could not be fixed automatically:
 express (major upgrade to 5.0.0)

我拿一个老项目试了。里面有 12 个 npm 依赖,deno audit 扫出来 3 个漏洞,deno audit fix 修掉了 2 个。剩下 1 个需要 express 从 4.x 升级到 5.0,属于 breaking change,工具没帮你做------这个设计是对的,major 升级不该自动搞。

踩坑点:deno audit fix 只处理 npm 依赖,jsr 包目前不走这条路。如果你的项目纯 Deno 生态,这个命令暂时用不上。

deno ci:CI 环境一行搞定

之前在 Docker 或 GitHub Actions 里装依赖,要写 deno install --frozen,还得确认 lockfile 存在。现在一个命令:

bash 复制代码
$ deno ci

它会做三件事:

  1. 检查 deno.lock 是否存在,没有直接报错
  2. 删除已有的 node_modules
  3. --frozen 模式安装,lockfile 和 config 不一致就失败

实际用起来比 npm ci 体验好。我在 GitHub Actions 里把 npm ci 换成 deno ci,工作流跑通了。Dockerfile 里也一样,原来三行变一行:

dockerfile 复制代码
# 之前
RUN npm ci --production
# 如果用 deno
RUN deno ci --prod

deno pack:TypeScript 直接打包成 npm 包

这个我觉得是最有意思的新功能。假设你有一个 Deno 项目:

json 复制代码
// deno.json
{
  "name": "@scope/my-lib",
  "version": "1.0.0",
  "exports": "./mod.ts"
}

跑一下 deno pack,直接生成一个 .tgz,里面有:

  • 转译好的 JavaScript
  • .d.ts 类型声明
  • 自动生成的 package.json
  • 模块说明符自动改写(jsr:@std/path 变成 @jsr/std__pathnpm:express@4 变成 express
bash 复制代码
$ deno pack
Creating scope-my-lib-1.0.0.tgz

$ deno pack --dry-run  # 看看会生成什么,不实际打包

我试着把一个 Deno 工具库用 deno pack 打包后发到 npm,Node 项目 npm install 后能直接用。以前做这件事要 tsc + tsup 或者 unbuild,配一堆东西。现在零配置。

有个细节:如果你的代码里用了 Deno.* API(比如 Deno.readTextFile),打包时会自动加上 @deno/shim-deno 作为依赖,让包在 Node 下也能跑。不想要这个 shim 可以加 --no-deno-shim

deno why:追踪依赖来源

装了一堆依赖后,有时候会发现 node_modules 里冒出一些不认识的包。deno why 帮你追踪某个包是被谁拉进来的:

bash 复制代码
$ deno why qs
qs@6.14.2
  npm:express@4 > qs@6.14.2

qs@6.15.1
  npm:express@4 > body-parser@1.20.5 > qs@6.15.1

同时支持 JSR 依赖:

bash 复制代码
$ deno why @std/path
@std/path@1.1.4
  jsr:@david/dax@0.43 > @std/path@1.1.4
  jsr:@david/dax@0.43 > @david/path@0.2.0 > @std/path@1.1.4
  jsr:@david/dax@0.43 > @std/fs@1.0.23 > @std/path@1.1.4

功能上跟 npm explain / pnpm why 一样,但 Deno 的好处是 npm 和 jsr 两套生态都能追踪。

deno transpile:纯粹的 TS 转 JS

有时候你只想把 TypeScript 转成 JavaScript,不要打包、不要模块改写、不要任何多余的事。deno transpile 干的就是这个:

bash 复制代码
$ deno transpile greeter.ts -o greeter.js

输入:

typescript 复制代码
interface User {
  name: string;
  balance: number;
}

export function greet(user: User): string {
  return `Hello ${user.name}, you have $${user.balance.toFixed(2)}`;
}

输出:

javascript 复制代码
export function greet(user) {
  return `Hello ${user.name}, you have $${user.balance.toFixed(2)}`;
}

类型信息干净地剥掉了,其他什么都没动。还能加 --declaration 同时输出 .d.ts,加 --source-map inline 输出 source map。

我在一个场景下用到了它:有个内部工具需要在不支持 TS 的运行时里跑(一个旧版嵌入式 V8),用 deno transpile 批量转换后直接扔进去,没出问题。以前用 esbuild --loader=ts 也行,但 deno transpile 不改模块结构,更干净。

Node 兼容性:42% → 76.4%

这个版本最"硬"的数据。Deno 跑 Node.js 自己的测试套件,通过率从 2.7 的 42% 涨到 76.4%(4457 个测试过了 3405 个)。500 多个 commit 改了几乎所有 node: 模块。

对比 Bun 1.3.14 的数据:40.6%(1810/4457)。

这意味着什么?你拿一个中等复杂度的 Node 项目,不改代码直接用 deno run 跑,成功的概率比以前高了不少。我试了几个场景:

  • Express 4.x 的 hello world:能跑
  • Fastify 基本路由:能跑
  • 用了 node:crypto 做哈希:能跑
  • node:child_process 调用外部命令:能跑
  • node:worker_threads 做简单并行:能跑

失败的场景也有:

  • 一些依赖 native addon 的包(.node 文件)
  • 涉及 node:vm 沙箱隔离的高级用法
  • 某些 node:net 的边缘 case

性能数据

这组数据挺猛的,都是官方在 Linux 上对比 Deno 2.7 测的:

指标 2.7 2.8 提升
冷启动 npm install 3319ms 906ms 3.66x
node:buffer base64 2594ms 844ms 3.07x
node:http 吞吐量 8339 req/s 18431 req/s 2.21x
node:crypto scrypt 1533ms 724ms 2.12x
node:http p99 延迟 20.86ms 11.89ms 1.75x

冷启动 npm install 3.66 倍提升是怎么做到的?四个优化叠加:

  1. 精简的包元数据请求 :npm registry 有个精简版 metadata 接口(application/vnd.npm.install-v1+json),只返回 resolver 需要的字段。之前 Deno 没用这个,现在用了。
  2. 并行依赖解析:之前解析器一次走一个父节点,现在并发展开所有分支。
  3. 解压从事件循环搬到线程池:大包的 gzip 解压以前会阻塞事件循环,现在丢到后台线程。
  4. tarball 解压拆成 CPU 和 I/O 两阶段:解压和写磁盘分开跑,换了更快的 gzip 解码器(libdeflater 替代 flate2)。

base64 的 3.07 倍提升更简单------换了 simdutf 库做编解码,一个 PR 搞定。

import defer:延迟模块执行

TC39 的新提案,Deno 率先支持了。用法:

javascript 复制代码
import defer * as heavy from "./heavy-module.js";

console.log("程序启动");
// heavy-module.js 的顶层代码还没执行

console.log(heavy.someValue);
// 这时候才真正执行 heavy-module.js

模块会被加载和解析,但顶层代码推迟到你第一次访问导出值时才执行。对启动时间敏感的场景有用------比如一个 CLI 工具有 20 个子命令,每个子命令依赖不同的重模块,用 import defer 可以只在命中对应子命令时才付执行成本。

实际用来替代 npm 可行吗

我花了半天把一个中等规模的 Node 项目(Express + Prisma + Bull 队列)的包管理器从 pnpm 换成 deno。

操作很简单:

bash 复制代码
# 删掉 node_modules 和 pnpm-lock.yaml
rm -rf node_modules pnpm-lock.yaml

# 用 deno 安装
deno install

deno 读 package.json,生成 deno.lock,创建 node_modules。安装速度确实快,冷缓存下比 pnpm 快了 2-3 倍(pnpm 已经很快了)。

但是------代码还是用 node 跑的,不是用 deno run。Prisma 的 CLI 和 Bull 的 Redis 连接那块,直接用 Deno 运行时还跑不通。所以现在的状态是:Deno 当包管理器用,Node 当运行时用。听起来有点奇怪,但确实可行,而且安装速度实打实地快。

小结

Deno 2.8 的策略很清楚:不要求你一步到位把项目迁移到 Deno,而是一点一点蚕食 Node 工具链。先当你的包管理器,再当你的安全审计工具,再当你的打包工具......等你发现大部分工具都在用 Deno 的时候,切换运行时就是最后一步了。

从实测来看,deno cideno packdeno audit fix 这三个命令的完成度很高,可以在生产项目里用。Node 兼容性 76% 说明大部分常见场景已经覆盖了,但复杂项目(native addon、底层网络操作)还得等。

值得试试的场景:

  • CI/CD 里用 deno ci 替代 npm ci
  • 有 Deno/JSR 库想发布到 npm 的,用 deno pack
  • 纯前端项目只需要包管理器的,用 deno install 替代 pnpm
相关推荐
鲲鹏AI探索局8 小时前
Marvis 初步体验:它不像套壳聊天框,但还不能叫“贾维斯”
人工智能·windows·aigc·ai-native
悟空码字9 小时前
显存不够?算力不足?多卡并行一站式解决方案
aigc·openai·ai编程
.柒宇.10 小时前
RHEL 10.1 从零部署 Ollama + Gemma4:e4b + Hermes Agent
linux·ai·aigc·agent·hermes agent
用户22385778251610 小时前
受够了openclaw的失忆,我本周爱上了Hermes agent
aigc
DigitalOcean10 小时前
芯片女皇预言GPU降温,CPU翻倍:AI算力大潮转弯了?
aigc·agent
imbackneverdie11 小时前
AI生成PPT全流程攻略
人工智能·信息可视化·aigc·powerpoint·ppt·科研工具·ai生图
手写码匠1 天前
深入解析大模型架构之争:全能通用模型 vs 领域专精模型
人工智能·深度学习·算法·aigc
sunneo1 天前
02-大模型选型的产品视角(系列四-AI产品战略)
人工智能·产品运营·aigc·产品经理·ai-native
莫雪歌1 天前
Java AI 应用开发实践:基于 Spring Boot 实现 Chat、Memory、RAG 与 Tool Calling
java·aigc