文章摘要
Deno 2.9发布,核心新功能是deno desktop,可用Web技术构建原生桌面应用,无需Electron样板代码,最终生成单一二进制文件。新版本还简化了Node项目迁移,deno install可直接读取npm、pnpm、yarn和Bun的锁文件。此外还包含CSS模块导入、更强的测试运行器、更快的启动速度和Node.js 26兼容性。
文章总结
好的,这是根据您的要求,对原文主要内容进行的中文重述,保留了关键细节,并删减了与主题无关的致谢和号召性用语部分。
Deno 2.9 版本发布:亮点与更新
Deno 2.9 版本正式发布,核心亮点是引入了 deno desktop 功能,允许开发者使用熟悉的 Web 技术栈构建原生桌面应用,无需 Electron 的样板代码,最终生成一个独立的二进制文件。同时,此版本极大地简化了从 Node.js 项目的迁移流程:deno install 现在可以直接读取 npm、pnpm、yarn 和 Bun 的锁文件,只需几个命令即可切换包管理器,无需复杂的迁移过程。此外,该版本还带来了 CSS 模块导入、更强大的测试运行器、更快的启动速度以及对 Node.js 26 的兼容性。
deno desktop:构建原生桌面应用
deno desktop 是 Deno 2.9 引入的实验性功能。它允许你将一个脚本或 Web 框架项目指向它,从而生成一个原生的、自包含的桌面应用程序。其 UI 在 WebView 中运行,逻辑在 Deno 中执行,最终编译成一个可分发的单一二进制文件。
最简单的应用是一个提供 UI 服务的入口点。Deno.serve() 在桌面入口点内部会自动绑定到 WebView 打开的端口,无需手动配置端口。deno desktop 还支持框架自动检测,可以自动识别并构建当前目录下的 Web 框架项目(如 Next.js、Astro、Fresh 等),并支持热模块替换。
原生桌面 API: 运行时内置了完整的原生桌面 API,如 Deno.BrowserWindow 用于控制窗口大小、位置、菜单等,并允许通过 window.bind() 在 WebView 和 Deno 之间建立桥梁。此外还有 Deno.Tray 用于系统托盘图标,以及 Deno.Dock(macOS)。prompt()、alert() 和 confirm() 会渲染为原生对话框,Deno.autoUpdate() 则提供了自动更新功能。
渲染后端: deno desktop 提供两种渲染后端:
* webview(默认):使用操作系统内置的引擎(Windows 的 WebView2,macOS 和 Linux 的 WebKit),无需额外捆绑,二进制文件小,启动快。
* cef:通过 Chromium Embedded Framework 捆绑 Chromium,确保跨平台渲染一致性,但会增加二进制文件大小。
分发: 基于与 deno compile 相同的机制,输出为独立的二进制文件。支持通过 --output 参数指定格式(如 .app、.dmg、.exe、.AppImage 等)。--target 和 --all-targets 参数支持跨平台编译,可在单个 Linux CI 运行器上为 Windows、macOS 和 Linux 构建二进制文件。
性能提升
Deno 2.9 在启动时间、内存使用和 HTTP 吞吐量方面均有显著提升。
* 启动速度:冷启动时间从 2.8 版本的 34.2 毫秒降至 17.3 毫秒,速度提升近 2 倍。
* 内存使用:在高负载下,内存占用显著降低。例如,在真实世界工作负载下,RSS 从 142 MB 降至 64 MB,减少了 2.2 倍;在传输 1 MiB 响应体时,RSS 从 197 MB 降至 63 MB,减少了 3.1 倍。
* HTTP 吞吐量:Deno.serve 的性能全面提升,真实世界工作负载的吞吐量提升了 1.27 倍。
CSS 模块导入
Deno 2.9 支持使用导入属性将 CSS 文件作为可构造样式表导入,符合 CSS 模块脚本的 Web 标准。导入结果是一个 CSSStyleSheet 实例,使得相同的代码无需打包步骤即可在 Deno 和浏览器中运行。此功能在 2.9 版本中需要通过 --unstable-raw-imports 标志启用。
从 npm、pnpm、yarn 和 Bun 迁移
迁移现有 Node 项目到 Deno 变得非常顺畅。
* 锁文件迁移:deno install 现在可以直接读取 package-lock.json、pnpm-lock.yaml、yarn.lock 或 bun.lock,并从中生成 deno.lock,保留精确的依赖版本和完整性哈希,不会出现意外的升级。
* 工作空间支持:Deno 现在能识别 pnpm 的 pnpm-workspace.yaml 文件,并将其配置迁移到 package.json 或 deno.json 中。
* node 命令兼容:当没有安装真实的 node 时,Deno 会在 PATH 中放置一个转发到自身的替代程序,并翻译 Node 的 CLI 参数,使得依赖 node 命令的工具(如 Next.js 的 Turbopack)可以无需修改地运行。
依赖管理
deno link和deno unlink:用于管理本地包链接,类似于npm link。deno list:新的子命令,用于打印项目声明的依赖及其解析版本,相当于npm ls。preferPackageJson设置:使deno add、deno install等命令管理package.json中的依赖,而非deno.json。- JSR 依赖在
node_modules中:通过jsrDepsInNodeModules选项,可以将jsr:依赖安装到node_modules目录中。 - 工作空间
node_modules:在工作空间中,deno install现在会在每个成员目录内创建node_modules并填充.bin。 - 锁文件合并冲突:
deno.lock中的 Git 合并冲突标记现在会被自动解决。
供应链安全
- 最小依赖年龄(默认启用):
min-release-age功能现在默认启用,拒绝安装任何发布时间少于 24 小时的 npm 包,以防止供应链攻击。 no-downgrade信任策略:新增的 opt-in 信任策略,通过评估每个包版本的发布方式(如 2FA 挑战、可信发布、来源证明)来防止因维护者令牌被盗而导致的降级攻击。
测试与覆盖率
Deno 的内置测试运行器得到了显著增强。
* 快照测试:测试上下文内置了 t.assertSnapshot() 方法,无需额外导入。
* 变更感知测试选择:deno test --changed 可以只运行受代码变更影响的测试。
* 重试与重复:支持对测试进行重试和重复运行,以处理不稳定测试。
* 覆盖率阈值:可以通过 --threshold 标志或在 deno.json 中配置覆盖率阈值,低于阈值时测试失败。
* 分片:deno test --shard=<index>/<count> 可以将测试文件分片,以便在 CI 机器上并行运行。
* 参数化测试:Deno.test.each 允许从输入表格中注册多个独立的测试用例。
deno compile
--include-as-is:将文件或目录嵌入到可执行文件的虚拟文件系统中,不进行模块解析或转译,适用于静态资源。- 持久化存储:编译后的二进制文件现在拥有真正的持久化存储,
Deno.openKv()、localStorage等 API 的数据会保存到平台的应用数据目录。 --bundle和--minify:实验性的--bundle标志可以先将入口点通过打包器处理,再进行嵌入,从而显著减小二进制文件体积。可与--minify结合使用。--watch模式:支持监听文件变化并自动重新编译。
deno fmt
- 非 JS 格式化器(HTML、CSS、SQL)已迁移到新的
lax引擎,只移动空白字符,不会重新排序或修改令牌,并能处理格式错误的输入。 - 新增了
sortNamedImports、sortNamedExports和json.trailingCommas等格式化配置选项。 - 支持读取
.editorconfig文件来填充未显式设置的格式化选项。
deno task
- 基于输入的缓存:通过声明任务的
files和output,Deno 可以在输入未改变时跳过任务执行,直接从缓存恢复输出。 - 并发控制:
--jobs标志用于限制同时运行的任务数量。 - 其他标志:包括
--if-present(任务不存在时正常退出)、--env-file(加载 dotenv 文件)和任务名称通配符排除组。
Node.js 兼容性
- Deno 的 Node.js 兼容性目标提升至 Node.js 26。
- 裸 Node 内置模块(如
import "fs")现在无需配置即可解析。 node:test模块获得了mock.module()、mock.timers、t.assert.fileSnapshot()等新功能。- 实现了
process.resourceUsage()和worker_threads.isInternalThread等更多运行时 API。 - Node-API 版本报告为 10。
Web Cryptography
- 实现了后量子密码学算法:ML-KEM(密钥封装)、ML-DSA(签名)和 SLH-DSA(签名)。
- 新增了
"ChaCha20-Poly1305"认证加密算法、SHA-3 系列、KMAC 和 Argon2 密钥派生。 - 新增了
SubtleCrypto.supports()方法用于运行时特性检测。 - 整个
crypto.subtle实现已从 JavaScript 移植到 Rust,减少了每次调用的开销。
Deno.serve
- 自动压缩默认关闭:
Deno.serve不再自动压缩响应体,需要显式启用。 - 旧版中止行为弃用:依赖
request.signal在成功响应后中止的旧行为已弃用。
其他
- Web Locks API:实现了 Web Locks API,用于协调异步任务和 Worker 对命名资源的访问。
navigator.userAgentData:实现了用户代理客户端提示 API。- Happy Eyeballs:
Deno.connect和Deno.connectTls现在实现了 Happy Eyeballs v2,用于更快的双栈网络连接。 Deno.watchFs的ignore选项:文件监视现在可以忽略指定路径。process.kill自身无需--allow-run:向当前进程发送信号不再需要--allow-run权限。deno watch子命令:新增deno watch作为deno run --watch-hmr的简短别名。
评论总结
根据评论内容,总结如下:
主要观点与论据:
对Deno稳定性的批评(评论1、3)
- 评论1指出Deno在Node兼容性上出现回归问题,且团队过度依赖Claude AI进行修复和写作,导致稳定性下降。关键引用:"I recently hit multiple Node compatibility regressions in Deno that were hard to debug";"they use Claude for everything now, from actual fixes to writing blog posts"
- 评论3反映迁移过程中遇到vite版本不兼容等细节问题,导致无法顺利使用。关键引用:"when I run the project using bun, it runs. When I try it using deno, it doesn't";"it's the lack of care for the details that really sours me"
对Deno商业模式的质疑(评论4)
- 认为VC投资损害了开源项目的可持续性,团队聚焦于盈利而非社区建设。关键引用:"Deno is a great example of how taking VC investments tanks the viability of an open source project";"Ryan Dahl is assuredly a poor steward of open source software"
对Deno的正面评价(评论5、6)
- 评论5(前Deno工程师)认为AI帮助Deno改进了Node兼容性,团队更注重标准。关键引用:"using Claude extensively to improve the node.js compat which was absolutely herculean if not impossible before AI";"I'd still bet on Deno in the long term"
- 评论6(游戏开发者)称赞Deno在游戏开发中的表现,如快速热重载、TypeScript支持。关键引用:"Deno has a good VSCode extension with test helpers and a fast language server";"Deno has never got in my way"
对Bun的对比评价(评论2、5)
- 评论2认为Bun的实时重载功能出色。关键引用:"definitely hard to beat Bun at the moment, the live reload is crazy good"
- 评论5批评Bun追求指标而牺牲稳定性。关键引用:"Bun has always played a bit fast and loose, chasing metrics at the cost of stability"
平衡性总结: - 批评方:关注稳定性、兼容性、商业模式问题 - 支持方:认可AI辅助改进、TypeScript支持、特定场景表现 - 中立:指出Deno有优点但需改进核心运行时