跳到主要内容
Deno 2.0

Deno 2 发布公告

观看我们的视频公告。

Deno 2 发布公告

Web 是人类最大的软件平台——为其构建意味着有可能 触达超过 50 亿人。但随着 近年来 Web 开发的加速发展,它也变得越来越复杂且难以管理。在编写单行代码之前,开发人员必须处理繁琐的配置和不必要的样板代码,而他们更愿意专注于交付产品并为用户创造价值。

然而,尽管存在 这些复杂性,作为 Web 语言的 JavaScript,在过去十年中 仍然是最流行的语言,而 TypeScript 迅速崛起成为第三名。这证明了 JavaScript 在 Web 开发中的普及性和实用性——也表明 JavaScript 不会消失。

为了简化 Web 编程,我们创建了 Deno:一个现代、一体化、零配置的 JavaScript 和 TypeScript 开发工具链。

  • 原生 TypeScript 支持
  • 基于 Web 标准:Promises、fetch 和 ES 模块
  • 内置电池:内置格式化程序、linter、类型检查器、测试框架、编译为可执行文件等等
  • 默认安全,就像浏览器一样

今天,成千上万的开发人员喜欢使用 Deno,代码仓库 已成为 GitHub 上 Star 数最高的 Rust 项目之一,仅次于 Rust 语言本身。

虽然我们在 Deno 1 中取得了巨大的成就,但下一个主要版本专注于大规模使用 Deno。这意味着与遗留 JavaScript 基础设施的无缝互操作性,以及对更广泛的项目和开发团队的支持。所有这些都不会牺牲 Deno 用户喜爱的简洁性、安全性和“内置电池”的特性。

今天,我们很高兴地宣布 Deno 2,其中包括

  • 与 Node.js 和 npm 的向后兼容性,允许您无缝运行现有的 Node 应用程序
  • 原生支持 package.jsonnode_modules
  • 使用新的 deno installdeno adddeno remove 命令进行包管理
  • 稳定的标准库
  • 支持私有 npm 注册表
  • 工作区和 monorepo 支持
  • 长期支持 (LTS) 版本
  • JSR:一个现代注册表,用于跨运行时共享 JavaScript 库

我们还在不断改进许多现有的 Deno 功能

  • deno fmt 现在可以格式化 HTML、CSS 和 YAML
  • deno lint 现在具有 Node 特定规则和快速修复
  • deno test 现在支持运行使用 node:test 编写的测试
  • deno task 现在可以运行 package.json 脚本
  • deno doc 的 HTML 输出具有改进的设计和更好的搜索功能
  • deno compile 现在支持 Windows 上的代码签名和图标
  • deno serve 可以跨多个核心并行运行 HTTP 服务器
  • deno init 现在可以搭建库或服务器
  • deno jupyter 现在支持输出图像、图表和 HTML
  • deno bench 支持关键部分,以实现更精确的测量
  • deno coverage 现在可以 HTML 格式输出报告

向后兼容,面向未来

Deno 2 向后兼容 Node 和 npm。这不仅允许您在当前的 Node 项目中运行 Deno,还可以逐步采用 Deno 的一体化工具链的各个部分。例如,您可以在克隆 Node 项目后使用 deno install 以闪电般的速度安装依赖项,或者运行 deno fmt 来格式化代码,而无需 Prettier。

Deno 2 与 Node 和 npm 的兼容性非常强大。Deno 2 理解 package.jsonnode_modules 文件夹,甚至 npm 工作区,允许您在任何使用 ESM 的 Node 项目中运行 Deno。如果需要进行小的语法调整,您可以使用 deno lint --fix 进行修复。

不喜欢 package.jsonnode_modules 目录的混乱,但仍然需要使用 npm 包?您可以直接使用 npm: 说明符导入 npm 包。在没有 package.jsonnode_modules 文件夹的情况下,Deno 会将您的包安装到全局缓存中。这允许您在单个文件中编写带有 npm 依赖项的程序——无需依赖清单、配置文件或 node_modules

import chalk from "npm:[email protected]";

console.log(chalk.blue("Hello, world!"));
// Hello, world! (in blue)

对于较大的项目,依赖清单可以简化依赖项管理。将 npm: 说明符放入 deno.json 文件中的导入映射中,可以导入包的裸名称

// deno.json
{
  "imports": {
    "chalk": "npm:[email protected]"
  }
}
import chalk from "chalk";

console.log(chalk.blue("Hello, world!"));
// Hello, world! (in blue)

通过使用 npm: 说明符导入 npm 包的功能,您可以在 Deno 中访问超过 200 万个 npm 模块。这甚至包括复杂的包,例如 gRPC、ssh2、Prisma、temporal.io、duckdb、polars。Deno 甚至支持高级功能,如 Node-API 原生插件。

最后,您可以将 Deno 2 与您最喜欢的 JavaScript 框架一起使用。Deno 2 支持 Next.js、Astro、Remix、Angular、SvelteKit、QwikCity 和许多其他框架。

使用 Deno 运行 create-next-app。

Deno 现在是一个包管理器,带有 deno install

Deno 2 不仅支持 package.jsonnode_modules 文件夹,还附带了三个重要的子命令,使您可以轻松安装和管理依赖项。

deno install 以闪电般的速度安装您的依赖项。如果您有 package.json,它会在瞬间创建一个 node_modules 文件夹。如果您不使用 package.json,它会将所有依赖项缓存到全局缓存中。

在冷缓存情况下,deno install 比 npm 快 15%,在热缓存情况下快 90%。我们在这方面已经非常快了,但预计在未来几周内会有更多改进,尤其是在冷缓存场景中。

Package install timings

deno adddeno remove 可用于在 package.jsondeno.json 中添加和删除包。如果您以前使用过 npm installnpm remove,这些命令会感觉非常熟悉。

deno add demo 1

deno add demo 2

JavaScript 注册表

今年早些时候,我们推出了一个 现代、开源的 JavaScript 注册表,名为 JSR.

它原生支持 TypeScript(您可以将模块作为 TypeScript 源代码发布),处理多个运行时和环境的模块加载复杂性,仅允许 ESM,从 JSDoc 风格的注释中自动生成文档,并且可以与类似 npm 和 npx 的系统一起使用(是的,JSR 将 TypeScript 转换为 .js.d.ts 文件)。

因为您将 TypeScript 上传到 JSR,所以它对正在发布的代码有出色的理解。这使我们能够为模块的发布和使用提供无缝的开发者体验。如果您对详细信息感兴趣,可以阅读我们关于 我们如何架构 JSR 的文章。

这是一个并排视频,比较了将包发布到 npm 与发布到 JSR 的过程。

标准库现在已稳定

虽然 npm 上有超过 200 万个模块可用,但搜索、评估和使用新模块的过程可能非常耗时。这就是为什么我们构建 Deno 标准库 超过 4 年的原因。

标准库由数十个经过严格审核的实用程序模块组成,涵盖从数据操作、Web 相关逻辑、JavaScript 特定功能等所有内容它在 JSR 上可用,并且可以被其他运行时和环境使用。

为了让您了解 Deno 标准库中提供了哪些类型的模块,以下是标准库模块及其在 npm 中的等效模块的部分列表

Deno 标准库模块 npm 包
@std/testing jest
@std/expect chai
@std/cli minimist
@std/collections lodash
@std/fmt chalk
@std/net get-port
@std/encoding rfc4648

有关可用包的完整列表,请访问 https://jsr.deno.org.cn/@std

私有 npm 注册表

Deno 2 中的私有 npm 注册表的工作方式与 Node 和 npm 中的工作方式相同,使用 .npmrc 文件

// .npmrc
@mycompany:registry=http://mycompany.com:8111/
//mycompany.com:8111/:_auth=secretToken

Deno 将自动拾取此 .npmrc 文件,并允许您拉取私有包,而无需额外的配置。

工作区和 Monorepos

Deno 2 还支持工作区,这是管理 Monorepos 的强大解决方案。只需在您的 deno.json 中使用 workspace 属性列出成员目录

// deno.json
{
  "workspace": ["./add", "./subtract"]
}

这些成员可以有单独的依赖项、linter 和格式化程序配置等。

Deno 不仅支持 Deno 包的工作区,还理解 npm 工作区。这意味着您可以创建一个混合的 Deno-npm monorepo(请参阅此示例),其工作区成员可以具有 package.json 或 deno.json

This sample monorepo contains a mix of npm members and Deno members.

此示例 monorepo 包含 npm 成员和 Deno 成员的混合。

您还可以通过运行 deno publish 将工作区成员发布到 JSR。例如,请参阅 Deno 标准库。无需手动弄清楚您需要以什么顺序发布包 - 只需运行 deno publish,它就会为您完成所有操作。

LTS

通常,大型组织中的开发团队需要在生产中使用新版本之前仔细审核它们。对于 Deno 每周的错误修复版本和 6 周一次的次要版本,这可能会变得非常耗时。为了使这些团队更容易,我们正在引入长期支持 (LTS) 发布通道

从 Deno 2.1 开始,LTS 通道将收到回溯移植的关键错误修复,为期六个月,确保为生产使用提供稳定可靠的基础。六个月后,将基于最新的稳定版本创建一个新的 LTS 分支。所有 LTS 版本都是免费提供的,并获得 MIT 许可,使需要更稳定和安全环境的任何团队都可以访问它们。

Starting with Deno 2.1, we’ll introduce a LTS branch that we’ll maintain and backport critical bug fixes to for six months.

从 Deno 2.1 开始,我们将引入一个 LTS 分支,我们将对其进行维护,并将关键错误修复回溯移植到该分支,为期六个月。

最后,对于需要高级支持的团队,我们推出了 Deno 企业版计划。它提供优先支持、直接访问我们的工程师、保证响应时间以及优先处理您的功能请求。我们已与 Netlify、Slack 和 Deco.cx 等公司合作,以帮助他们的工程师更快地行动,并为他们的用户交付更多价值。

Deno 速度很快!

我们投入了巨大的努力,使 Deno 在各种真实场景中都变得快速。我们的重点是交付在日常 JavaScript 和 TypeScript 开发中真正重要的性能改进——无论是启动时间、处理复杂请求还是整体效率。

虽然基准测试永远无法说明全部情况,但它们可以提供有关运行时在何处表现出色的见解。以下是一些基准测试,展示了 Deno 的优势,证明了其为开发和生产环境提供一流性能的能力。

Please refer to the links beneath each chart for further detail and reproducible steps.

请参阅每个图表下方的链接,以获取更多详细信息和可重复的步骤。

更正: 上面显示的第一个 HTTP 基准测试是使用 Deno 1.45 而不是 Deno 2.0 进行的。实际上,Deno 2.0 比此处指示的慢约 20%。这种差异是由于我们最近禁用了 V8 指针压缩,以解决用户超出 4GB 堆限制的情况。我们计划尽快重新启用指针压缩,因为它是大多数用户的理想默认设置,并为需要更大堆的用户引入 deno64 构建。

常见问题解答

如果 Deno 完全向后兼容 Node,为什么我应该使用 Deno 而不是 Node?

虽然 Deno 可以运行 Node 程序,但它的设计目的是推动 JavaScript 和 TypeScript 的发展。Deno 提供了 Node 缺乏的功能,例如原生 TypeScript 支持、Web 标准 API、用于 JavaScript 开发的完整工具链以及默认安全的执行模型——所有这些都集成在一个没有外部依赖项的可执行文件中。与 Node 相比,使用 Deno 可以节省您的设置和配置时间,让您更快地开始编码并交付价值。

当运行 Node 程序时,Deno 的选择加入权限系统是否会生效?

是的,当运行 Node 程序或导入 npm 模块时,Deno 的默认安全执行模型仍然适用,确保相同的安全级别。

为什么要使用新徽标?可爱的恐龙吉祥物怎么了?

从一开始,雨中可爱的蜥脚类恐龙一直是 Deno 的形象。它古怪的魅力一直是 Deno 的标志,但设计从未统一——至少有两个“官方”版本和无数变体。随着 Deno 2.0 的发布,我们认为现在是时候进行更新了。

我们希望保留 Deno 用户喜爱的原始角色的精髓,同时使其外观更加精致,以匹配 Deno 的专业和生产级特性。在重新设计过程中,我们意识到下雨的背景虽然怀旧,但扩展性不好,而且经常被忽视。它太繁琐了,尤其是在小尺寸下,所以我们不得不放弃它。

经过多次迭代,我们发现将设计简化为核心元素可以达到适当的平衡——简单而友好,但又严肃而可靠——就像 Deno 一样。

(别担心,可爱的恐龙还在!)

Deno 最初的愿景是实现 JavaScript 的现代化。但是,在向后兼容性方面投入了大量工作之后,Deno 的原始愿景还剩下什么?

重写整个 JavaScript 生态系统是不切实际的。随着 Deno 扩展到小型程序之外,我们认识到支持 Node 和 npm 兼容性至关重要——特别是对于 gRPC 和 AWS SDK 等工具,从头开始重写这些工具是不切实际的。

但 Deno 的目标不是成为 Rust 中的 Node 克隆或直接替代品。我们的目标是提升 JavaScript 的水平,超越 2010 年代的 CommonJS,并以开发人员可以实际采用的方式缩小服务器端和浏览器环境之间的差距。我们拒绝接受 JavaScript 必须仍然是工具不匹配和无休止的转译层,无法进化的局面。

Deno 的原始愿景仍然是我们一切工作的核心。这包括原生 TypeScript 支持、内置 Web 标准(如 Promises、顶层 await、Wasm、fetch 和 ES 模块)以及内置电池的工具链——所有这些都打包在一个单一的、无依赖项的可执行文件中。当然,它默认是安全的,就像 Web 一样。

支持 npm 只是使 Deno 更加通用的一个步骤。我们的使命是提供一个现代、精简的工具链,以增强 JavaScript 体验——而不仅仅是支持遗留代码。虽然我们调整了方法,但我们的愿景仍然不变:简化和增强 Web 开发。

我喜欢 Deno,因为它不需要任何配置文件,但是随着新的包管理器添加,Deno 2 是否变得更像 Node,需要 package.json 才能添加依赖项?

完全不是。您仍然可以运行单文件程序或脚本,而无需任何配置或依赖清单——这方面没有任何改变。新的包管理命令(deno installdeno adddeno remove)是可选工具,旨在简化依赖项管理,无论您使用 deno.json 还是 package.json 文件。它们对于更大、更复杂的项目特别有用,但如果您喜欢无配置的简洁性,它们也不会妨碍您。

我们的核心目标之一是 Deno 可以向下扩展到简单的单文件程序,这些程序可以导入任何包,而无需额外的仪式。例如,在 Jupyter 笔记本或快速脚本等上下文中,您可以轻松地执行

import * as Plot from "npm:@observablehq/plot";

同时,Deno 可以向上扩展以处理具有多个文件甚至多个包的大型项目,例如在 monorepos 中。这种灵活性确保 Deno 对于小型脚本和大型生产级应用程序都同样有效。

我有一个 Fresh 项目。如果我升级到 Deno 2,会有破坏性更改吗?

不会!您的 Fresh 项目应该与 Deno 2 开箱即用——无需任何更改。

我应该何时期待 Deno 2 在 Deno Deploy 上线?

随时!

下一步是什么

Deno 2 采用了开发人员喜爱的 Deno 1.x 的所有功能——零配置、用于 JavaScript 和 TypeScript 开发的一体化工具链、Web 标准 API 支持、默认安全——并使其完全向后兼容 Node 和 npm(在 ESM 中)。这不仅使在任何 Node 项目中运行 Deno 变得简单,而且还允许在更大、更复杂的项目中逐步采用 Deno(例如,运行 deno fmtdeno lint)。凭借改进的包管理、JSR 以及为更高级的开发团队提供的大量功能,Deno 已准备好简化和加速您今天的开发。

但是,鉴于 Deno 的广泛功能,我们无法在一篇博文和视频中涵盖所有内容。Deno 有许多令人兴奋的功能和用例,我们没有提及。例如,能够使用 deno compileJavaScript 游戏转换为桌面可执行文件,并支持交叉编译(是的,Windows)。或者 Deno 的 Jupyter 笔记本支持,允许您在 TypeScript 和 @observable/plot 中探索和可视化数据。或者使用 deno doc 从您的 JSDoc 注释和源代码生成文档或静态文档站点。

Deno’s features at a glance.

我们邀请您今天试用 Deno 2,体验 JavaScript 和 TypeScript 开发的未来。立即开始使用 Deno 2

加入我们的社区,让我们共同塑造 JavaScript 的未来!


Tweet 1


Tweet 2


Tweet 3