Deno 2.8

Hacker News Top 工具

摘要

Deno 2.8 发布,新增了子命令:deno audit fix、deno bump-version 以及用于 CI 工作流的 deno ci。

暂无内容
查看原文
查看缓存全文

缓存时间: 2026/05/22 15:24

# Deno 2.8 发布 来源:https://deno.com/blog/v2.8 Deno 2.8 来了。这是我们迄今为止最大的次要版本,我们很高兴与大家分享。要升级到 Deno 2.8,请在终端中运行以下命令: 如果尚未安装 Deno,请运行以下命令之一进行安装,或在此处了解安装方法 (https://docs.deno.com/runtime/manual/getting_started/installation)。 ``` curl -fsSL https://deno.land/install.sh | sh iwr https://deno.land/install.ps1 -useb | iex ``` ## 新子命令 ### `deno audit fix` `deno audit` (https://docs.deno.com/runtime/reference/cli/audit/)(在 2.6 版本中引入 (https://deno.com/blog/v2.6#security-auditing-with-deno-audit))可报告依赖树中 npm 包的漏洞。新的 `deno audit fix` 子命令更进一步,会自动将有问题的包升级到仍满足版本约束的最接近的修补版本(#32909 (https://github.com/denoland/deno/pull/32909)、#34273 (https://github.com/denoland/deno/pull/34273))。相同的行为也可通过 `deno audit` 的 `--fix` 标志使用: ``` $ 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 ╭ Express.js Open Redirect in malformed URLs │ Severity: moderate │ Package: express │ Vulnerable: <4.19.2 ╰ Info: https://github.com/advisories/GHSA-rv95-896h-c2vc 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) ``` 任何需要主版本号升级的内容都会单独列出,以便你决定是否放宽约束。详细了解 `deno audit fix` (https://docs.deno.com/runtime/reference/cli/audit/#auto-fixing-vulnerabilities)。 ### `deno bump-version` `deno bump-version` 会更新 `deno.json` 或 `package.json` 中的版本字段(#30562 (https://github.com/denoland/deno/pull/30562)): ``` $ deno bump-version patch $ deno bump-version minor $ deno bump-version major $ deno bump-version prerelease ``` 在工作区中,它的功能更多。在工作区根目录运行,相同的增量将应用于每个成员包,根配置中的 `jsr:` 版本约束和导入映射会被就地重写,以便跨包引用保持同步(#33689 (https://github.com/denoland/deno/pull/33689)): ``` $ deno bump-version patch ``` 如果不加增量参数,工作区模式会切换到从 Conventional Commits (https://www.conventionalcommits.org/) 推导每个包的增量,范围是基准引用与当前分支之间。它支持作用域提交、通配符 `*` 作用域、`BREAKING`/`!` 用于主版本增量、预发布增量以及 0.x.y 语义版本规则,并将自基准引用以来的任何手动版本编辑视为权威。 ``` $ deno bump-version --base=main --dry-run ``` `--dry-run` 会打印计划更改而不实际写入,`--start`/`--base` 允许在你不需要默认的“当前分支自最新标签以来的提交”时固定比较范围。详细了解 `deno bump-version` (https://docs.deno.com/runtime/reference/cli/bump_version/)。 ### `deno ci` CI 脚本和 Dockerfile 在安装时只需要一件事:“给我锁文件里写的精确内容,如果有任何不一致就大声报错。” 在此之前,这意味着要记住 `deno install` 上正确的标志组合。Deno 2.8 新增了一个专用的 `deno ci` (https://docs.deno.com/runtime/reference/cli/ci/) 子命令(#34235 (https://github.com/denoland/deno/pull/34235)): 如果 `deno.lock` 缺失,它会报错;删除任何现有的 `node_modules` 目录;然后使用 `--frozen` 运行安装,因此锁文件必须与配置文件完全匹配。将其放入 CI 步骤或 `Dockerfile` 中,你会得到一个清晰、可搜索的“可重现安装”信号,无需考虑标志。`--prod` 和 `--skip-types` 的工作方式与 `deno install` 相同。 ### `deno pack` `deno pack` 更接近 `tsc` + `npm pack` 的组合,而不仅仅是 `npm pack`:它一步将 Deno 或 JSR 项目构建成可发布到 npm 的 tarball(#32139 (https://github.com/denoland/deno/pull/32139))。 给定一个像这样的 `deno.json`: deno.json ``` { "name": "@scope/my-lib", "version": "1.0.0", "exports": "./mod.ts" } ``` ...运行 `deno pack` 会生成一个 `scope-my-lib-1.0.0.tgz`,即可用于 `npm publish`。tarball 包含: - 生成的 `package.json`,带有 `type: "module"`、条件 `exports`(types/import/default)以及提取的运行时依赖。 - 你的 TypeScript 转译为 JavaScript。 - 通过 `deno publish` 使用的相同快速检查管道提取的 `.d.ts` 声明文件(传递 `--allow-slow-types` 跳过)。 - 如果项目根目录中存在 `README` 和 `LICENSE` 文件,则包含它们。 在此过程中,`deno pack` 会重写 specifier,使发布的包能够在 npm 生态系统中正常工作:`jsr:@std/path` 变为 `@jsr/std__path`,`npm:express@4` 变为 `express`,相对的 `./utils.ts` 导入变为 `./utils.js`,而 `node:` 内置模块保持不变。 如果你的代码调用了 `Deno.*` API,包会自动将 `@deno/shim-deno` 作为依赖,以便它也能在 Node 上运行(使用 `--no-deno-shim` 退出)。文件选择基于图:只有从声明的 `exports` 可达的模块才会被打包,而不是目录中的所有文件。 Tarball 是确定性的(条目排序、固定时间戳和权限),这对于可重现构建和内容寻址注册表很重要。 ``` $ deno pack $ deno pack --dry-run $ deno pack --set-version 2.0.0 $ deno pack --output my-package.tgz $ deno pack --ignore=tests/ $ deno pack --allow-dirty ``` 详细了解 `deno pack` (https://docs.deno.com/runtime/reference/cli/pack/)。 ### `deno transpile` 一个新的子命令,从 TypeScript、JSX 和 TSX 中剥离类型,并将纯 JavaScript 写入磁盘。无打包、无模块重写、无配置。仅执行发射步骤。 greeter.ts ``` interface User { name: string; balance: number; } export function greet(user: User): string { return `Hello ${user.name}, you have $${user.balance.toFixed(2)}`; } ``` ``` $ deno transpile greeter.ts -o greeter.js ``` greeter.js ``` export function greet(user) { return `Hello ${user.name}, you have $${user.balance.toFixed(2)}`; } ``` `deno transpile` 接受多个文件、`--outdir` 用于批量输出、`--source-map separate|inline` 以及 `--declaration` 用于在 JS 旁边输出 `.d.ts`。当你需要发布纯 JS 产物或为不支持原生 TypeScript 的运行时预构建 TS 时非常有用。 详细了解 `deno transpile` (https://docs.deno.com/runtime/reference/cli/transpile/)。 ### `deno why` `deno why <package>` 通过从你的直接依赖向下遍历到相关包来解释某个包为何被安装(#32908 (https://github.com/denoland/deno/pull/32908))。它相当于 `npm explain`/`pnpm why`/`yarn why`。它同时适用于 npm 和 JSR 依赖(#34227 (https://github.com/denoland/deno/pull/34227))。 假设一个项目混合使用了两个注册表: deno.json ``` { "imports": { "express": "npm:express@^4", "dax": "jsr:@david/dax@^0.43" } } ``` `deno why` 会追踪一个 npm 传递依赖回到其 npm 入口点: ``` $ deno why qs [email protected] npm:express@4 > [email protected] [email protected] npm:express@4 > [email protected] > [email protected] ``` ...以及一个 JSR 传递依赖回到其 JSR 入口点,树中的每条路径都会单独列出: ``` $ deno why @std/path @std/[email protected] jsr:@david/[email protected] > @std/[email protected] jsr:@david/[email protected] > @david/[email protected] > @std/[email protected] jsr:@david/[email protected] > @std/[email protected] > @std/[email protected] jsr:@david/[email protected] > @david/[email protected] > @std/[email protected] > @std/[email protected] ``` 当你只关心树的某个分支时,可以用 `deno why [email protected]` 或 `deno why @std/[email protected]` 固定到特定版本。 详细了解 `deno why` (https://docs.deno.com/runtime/reference/cli/why/)。 ## Deno 现在默认使用 `npm:` Deno 2.8 在 CLI 中移除了 `npm:` 前缀要求:`deno add` 和 `deno install` 现在默认将无前缀的名称视为 npm 包(#33246 (https://github.com/denoland/deno/pull/33246)),因此你输入的命令与每个 Node 开发者肌肉记忆中的相同。 ``` $ deno add express error: express is missing a prefix. Did you mean `deno install npm:express`? $ deno add express Add npm:[email protected] Dependencies: + npm:[email protected] ``` `npm:` 前缀仍然有效(并且在 `import` specifier 中仍然需要),但你在 CLI 中不必输入它。JSR 包保留 `jsr:` 前缀,因此两个注册表保持明确。 通过此更改,`deno install` 成为现有 Node 项目中 `npm install`、`yarn` 或 `pnpm install` 的直接替代品。它读取 `package.json`,写入兼容的 `node_modules` 布局,并且在冷缓存上比 2.7 **快 3.66 倍** (https://deno.com/blog/v2.8#performance);得益于 Deno 跨项目共享的全局缓存,热安装甚至更快。将 Deno 作为包管理器使用,并在 Node 上继续运行其他所有内容。 详细了解 `deno install` (https://docs.deno.com/runtime/reference/cli/install/)。 ## Node.js API 兼容性 Node.js 兼容性在过去几年中一直是我们的重要关注点。我们很高兴地宣布,在 Deno 2.8 中取得了巨大飞跃:针对 Node 自身测试套件的通过率从 Deno 2.7 的约 **42% 跃升至 76.4%**(4,457 个测试中有 3,405 个通过);自 Deno 2.7 以来已提交 500 个提交,几乎涉及每个 `node:` 模块。 我们在 node-test-viewer.deno.dev (https://node-test-viewer.deno.dev/) 密切跟踪这个百分比: 在 Linux、Windows 和 Darwin 上,Node.js 测试套件的通过率随时间变化,从 2026 年 1 月的约 42% 攀升到 2026 年 5 月的 70% 左右。别介意 1 月那个 100% 的波动 😅 与相同套件上的 Bun 1.3.14 进行对比: Node.js 测试套件通过率(4,457 个测试) - **Deno v2.8** 76.4% (3,405) - Bun 1.3.14 40.6% (1,810) 排除提前退出的测试: - **Deno 2.8 72.4%** (3,229 / 4,457) vs **Bun 1.3.14 36.4%** (1,623 / 4,457)。 Deno 2.8 还使 Node 兼容性在实际项目中更轻量:许多 Node 内置模块现在被延迟加载,因此不使用它们的程序启动更快(稍后导入这些模块之一会支付一个小的延迟加载成本)。几个 `node:*` 热路径也得到了专用优化;请参阅下面的性能部分获取基准测试数据。 ## 性能 Deno 2.8 在包管理器、`node:*` 兼容性、HTTP 服务和 Web 平台上带来了显著的加速。在 Linux 上与 Deno 2.7.1 进行对比: | 基准测试 | Deno 2.7 (灰色) vs 2.8 (蓝色) | 加速比 | |------------|---------------|----------| | 冷 npm install | 越低越好 | 3.66x 更快 | | `node:buffer` base64 | 越低越好 | 3.07x 更快 | | `node:http` 吞吐量 | 越高越好 | v2.7 8,339 req/s **v2.8** 18,431 req/s 2.21x 更快 | | `node:crypto` scrypt | 越低越好 | 2.12x 更快 | | `node:http` p99 延迟 | 越低越好 | v2.7 20.86 ms **v2.8** 11.89 ms 1.75x 更快 | | `node:http` 分块写入 | 越高越好 | v2.7 6,635 req/s **v2.8** 11,521 req/s 1.74x 更快 | | 分块写入 p99 | 越低越好 | v2.7 25.39 ms **v2.8** 15.68 ms 1.62x 更快 | | `node:fs` 递归 `cpSync` | 越低越好 | 1.49x 更快 | | Worker `MessagePort` ping-pong | 越低越好 | v2.7 1,678 ms **v2.8** 1,270 ms 1.32x 更快 | (每个数量级共享一个比例尺。进程基准测试:30 次 `hyperfine` 样本。HTTP 基准测试:10 次 30 秒 `oha` 运行。) **冷 npm 安装。** 一个入口点导入 React、Vite、Babel 解析器和 ESLint,在 Deno 2.8 中安装**快 3.66 倍**,从 `3,319ms` 降至 `906ms`,在新 `DENO_DIR` 上。在 30 个样本中,加速比的引导 95% 置信区间为 `3.53x` 到 `3.75x`。促成这一数字的一些更改: - **缩写包清单** (#32364 (https://github.com/denoland/deno/pull/32364))。npm 注册表公开了一个较小的“缩写”元数据文档 (`application/vnd.npm.install-v1+json`),仅包含解析器需要的字段;Deno 现在使用这个较小的文档进行解析,仅在需要时才获取完整包清单。 - **并行 npm 解析** (#32416 (https://github.com/denoland/deno/pull/32416))。解析器以前一次遍历一个父节点。Deno 2.8 也扩展到父节点,因此依赖树中独立的分支不再相互等待。 - **从异步事件循环中解压缩** (#32400 (https://github.com/denoland/deno/pull/32400))。大型包清单的 gzip 解压缩可能会阻塞共享同一连接的其他 HTTP/2 流。Deno 2.8 将注册表主体解压缩路由到阻塞线程池,释放事件循环用于更多并发请求。 - **tarball 提取拆分为 CPU 和 I/O 阶段** (#32408 (https://github.com/denoland/deno/pull/32408))。Tarball 提取以前是一个紧密循环。现在它分为 CPU 绑定的解压缩阶段和 I/O 绑定的文件系统写入阶段。与 **libdeflater + 预分配缓冲区** (#32511 (https://github.com/denoland/deno/pull/32511))(比标准 `flate2` 更快的 gzip 解码器)以及 **tarball 提取期间更少的系统调用** (#32541 (https://github.com/denoland/deno/pull/32541)) 配合使用。 **`node:http`。** Hello-world `node:http` 吞吐量提升超过两倍(`2.21x`),p99 延迟降低约 40%;分块响应获得类似增益(`1.74x` 吞吐量,`1.62x` 尾部延迟)。 **全面的 base64。** 一项更改,将 `base64` 编码/解码切换到 simdutf (https://github.com/simdutf/simdutf) (#32743 (https://github.com/denoland/deno/pull/32743)),推动 **`node:buffer` base64 快 3.07 倍**(从 `2,594ms` 降至 `844ms`),并且 `atob`/`btoa` 以及所有接触 base64 的 Web API 路径也获得相同的加速。 **其他 `node:*` 热路径。** `node:crypto` 中的 `scryptSync` 现在快 2.12 倍,基于 Rust 的递归 `node:fs` `cpSync` 快 1.49 倍,Worker 之间通过 `MessagePort` 交换消息现在快 1.32 倍。 **`Deno.serve`。** 原生 `Deno.serve` 获得了直接分发到 JS 处理程序、完全缓冲响应体的快速路径以及更轻量的 `Vary` 处理(#33845 (https://github.com/denoland/deno/pull/33845)、#33844 (https://github.com/denoland/deno/pull/33844)、#33892 (https://github.com/denoland/deno/pull/33892))。一个 hello-world 基准测试显示吞吐量提升 1.13 倍,p99 延迟中位数降低 1.20 倍。 **其他优化。** 一系列较小的胜利,处处可见: - `TextEncoder`/`TextDecoder` 针对 ASCII / Latin-1 / 短字符串的快速路径(#32735 (https://github.com/denoland/deno/pull/32735)、#33674 (https://github.com/denoland/deno/pull/33674)、#33675 (https://github.com/denoland/deno/pull/33675)、#34055 (https://github.com/denoland/deno/pull/34055))。 - `FormData`、`URLSearchParams` 和 `Headers` 上的线性时间 `set`/`delete`(#33961 (https://github.com/denoland/deno/pull/33961)),不再有大型头部集上的二次方爆炸。 - `URLPattern` 操作减少 serde 开销和 GC 压力(#32766 (https://github.com/denoland/deno/pull/32766)),因此每个请求都匹配的中间件变得更轻量。 - 在 op 慢路径中实现零拷贝 V8 到 Rust 字符串转换(#32688 (https://github.com/denoland/deno/pull/32688))以及 `op_decode` 的 SIMD ASCII 快速路径(#33720 (https://github.com/denoland/deno/pull/33720)),`Response.text()`、`File.text()` 和 FormData 解析都依赖于此。 - V8 线程池限制为 4 个线程(#33697 (https://github.com/denoland/deno/pull/33697)),在典型桌面上减少约 1 MB RSS。 - 模块加载后(#32662 (https://github.com/denoland/deno/pull/32662))和 Worker 终止时(#32617 (https://github.com/denoland/deno/pull/32617))的 `malloc_trim`,修复了在 Linux 上加载大量包时 RSS 膨胀 3-5 倍的问题。

相似文章

Deno 2.9

Hacker News Top

Deno 2.9 引入了 `deno desktop`,用于使用 Web 技术构建原生桌面应用程序,同时改进了 Node.js 兼容性、CSS 模块导入和更快的启动速度。

Deno Desktop

Hacker News Top

Deno Desktop 是 Deno 2.9 中的一个新功能,它可以将任何 Deno 项目转变为自包含的桌面应用程序,具有小型二进制文件、框架自动检测、内置自动更新及交叉编译支持。

Deno Desktop

Lobsters Hottest

Deno Desktop 是一项新功能,它将 Deno 项目打包成独立的桌面应用程序,使用 Chromium 或原生 Webview,相比 Electron 更轻量;目前处于 canary 阶段,存在一些错误。

我希望 Deno 能继续做它最擅长的事

Lobsters Hottest

一篇反思性文章,批评 Deno 转向与 Node.js 兼容的做法,认为这削弱了其原本简洁、零配置的理念,而正是这些特点让开发者对其青睐有加。

Claw Patrol: 一个面向代理的开源安全防火墙

Lobsters Hottest

Deno 开源了 Claw Patrol,这是一个面向 AI 代理的安全防火墙,它通过隧道路由流量、解析协议、注入凭据并执行规则,以防止危险操作(如删除 SQL 或 kubectl 命令)。