译:发布 Deno 2

原文:https://deno.com/blog/v2.0
译者:ChatGPT 4 Turbo

发布 Deno 2

Web 是人类最大的软件平台 —— 针对它进行构建意味着潜在地触达超过 50 亿的人口。但随着近年来网络开发的加速,它也变得越来越复杂,难以管理。在编写一行代码之前,开发人员必须处理繁琐的配置和过多的样板内容,而他们更希望专注于产品发布和为用户提供价值。

尽管存在这些复杂性,JavaScript,Web 的语言,在过去十年里一直是最受欢迎的语言,而 TypeScript 迅速成为第三大流行语言。这证明了 JavaScript 在 Web 开发中的普遍性和有用性——也是 JavaScript 不会消失的标志。

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

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

如今,成千上万的开发者喜欢使用 Deno,仓库成为GitHub 上星级最高的 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:chalk@5.3.0";

console.log(chalk.blue("Hello, world!"));
// Hello, world!(用蓝色显示)

对于大型项目,依赖清单能够简化你的依赖管理。将 npm: 指定符放入 deno.json 文件的导入映射中,可以直接导入包的裸名:

// deno.json
{
  "imports": {
    "chalk": "npm:chalk@5.3.0"
  }
}
import chalk from "chalk";

console.log(chalk.blue("Hello, world!"));
// Hello, world!(用蓝色显示)

通过 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 run -A npm:create-next-app@latest

Deno 现已成为一个包管理器,拥有 deno install

Deno 2 不仅支持 package.jsonnode_modules 文件夹,还附带了三个重要的子命令,让你能够轻松安装和管理你的依赖。

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

deno install 在冷缓存下比 npm 快 15%,在热缓存下快 90%。我们在这里已经非常快了,但请期待在接下来的几周里,特别是在冷缓存场景中的更多改进。

包安装时间

deno adddeno remove 可用于向你的 package.jsondeno.json 添加或从中移除包。如果你之前使用过 npm installnpm remove,这些将会感觉非常熟悉。

deno add demo 1

deno add demo 2

JavaScript 注册表

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

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

因为你上传 TypeScript 到 JSR,它对正在发布的代码有着出色的理解能力。这使我们能够为发布和使用模块提供无缝的开发者体验。如果你对细节感兴趣,可以阅读我们关于如何构建 JSR 的帖子。

标准库现已稳定

尽管 npm 上有超过 200 万个模块可用,但寻找、评估和使用新模块的过程可能会耗费时间。这就是为什么我们花了 4 年多的时间来构建 Deno 标准库

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

为了让你对 Deno 标准库中可用的模块类型有所了解,这里有一个标准库模块及其在 npm 中对应包的部分列表:

如需查看可用包的完整列表,请访问 https://jsr.io/@std

私有 npm 仓库

Deno 2 中的私有 npm 仓库工作方式与 Node 和 npm 中的 .npmrc 文件一样

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

Deno 会自动识别 .npmrc 文件,并允许你不需额外配置即可拉取私有包。

工作区和多仓库

Deno 2 也支持工作区,这是管理多仓库的一个强大解决方案。 只需在你的 deno.json 中使用 workspace 属性来列出成员目录:

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

这些成员可以有各自的依赖、linter 和格式化配置等。

Deno 不仅支持 Deno 包的工作区,它还理解 npm 工作区这意味着你可以创建一个混合的 Deno-npm 多仓库(见此示例),其中工作区成员可以有 package.json 或 deno.json:

此示例多仓库包含 npm 成员和 Deno 成员的混合。

此示例多仓库包含 npm 成员和 Deno 成员的混合。

你也可以通过运行 deno publish 将工作空间成员发布到 JSR。举个例子,请参阅Deno 标准库。无需手动去弄清楚你需要以什么顺序发布你的包 – 只需运行 deno publish,它将为你完成所有操作。

LTS

通常,在较大组织中的开发团队需要在生产中使用新版本之前仔细审核新发布的版本。随着 Deno 的每周错误修复发布,以及每 6 周的小版本发布,这可能变得非常耗时。为了让这些团队更加轻松,我们引入了长期支持(LTS)发布通道

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

从 Deno 2.1 开始,我们将引入一个 LTS 分支,我们将维护并向其回滚关键错误修复,为期六个月。

从 Deno 2.1 开始,我们将引入一个 LTS 分支,我们将维护并向其回滚关键错误修复,为期六个月。

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

Deno 是快速的!

我们投入了巨大的努力,使 Deno 在广泛的现实世界场景中都表现出色的速度。我们的重点是在每天的 JavaScript 和 TypeScript 开发中提供真正重要的性能改进——无论是启动时间、处理复杂请求,还是整体效率。

虽然基准测试永远无法讲述完整的故事,但它们可以提供有关运行时在哪些方面表现出色的见解。以下是一些展示了 Deno 强项的基准测试,证明了它在为开发人员和生产环境提供顶级性能方面的能力。

请参考每个图表下方的链接,了解更多详情和可重现的步骤。

编辑: 上面显示的 第一个 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 开发工具链,以及一个默认安全的执行模型——所有这些都包含在一个无需外部依赖的单个可执行文件中。使用 Deno 而不是 Node 可以节省您在设置和配置上的时间,让您更快地开始编码和交付价值。

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

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

新 logo 是怎么回事?那个可爱的恐龙吉祥物去哪了?

自从一开始,那个雨中的可爱蜥脚类恐龙就是 Deno 的面孔。它的古怪魅力一直是 Deno 的一个标志,但设计从未一致——至少有两个“官方”版本和无数的变体。随着 Deno 2.0,我们决定是时候进行一次刷新了。

我们希望保留 Deno 用户喜爱的原始角色的精髓,同时给它一个更精致的外观,以匹配 Deno 的专业性和生产级别的本质。在重新设计过程中,我们意识到,虽然怀旧,但雨景背景并不适合放大,而且常常被忽视。它太繁忙了,特别是在小尺寸时,所以我们不得不将它放弃。

经过多次迭代,我们发现将设计简化到核心元素能够取得正确的平衡——简单而友好,但又严肃可靠——就像 Deno 一样。

(不用担心,那个可爱的恐龙还在!)

Deno 一开始就有一个雄心勃勃的愿景,要使 JavaScript 现代化。但是,在所有花费在向后兼容性上的工作之后,Deno 的原始愿景还剩下什么?

重写整个 JavaScript 生态系统是不切实际的。随着 Deno 超越小程序的规模,我们认识到支持 Node 和 npm 的兼容性至关重要——尤其是对于像 gRPC 和 AWS SDKs 这样从头重写是不切实际的工具而言。

但 Deno 的目标不是成为一个用 Rust 编写的 Node 克隆或一个直接替代品。我们的目标是提升 JavaScript,超越 2010 年代的 CommonJS,缩小服务器端和浏览器环境之间的差距,以一种开发人员可以实际采用的方式。我们拒绝接受 JavaScript 必须保持一团错综复杂的工具和无休止的转译层,无法进化的状态。

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

支持 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 compile 将 JavaScript 游戏转换为桌面可执行文件并支持跨平台编译(是的,Windows)。==或者 Deno 的 Jupyter 笔记本支持,它允许您在 TypeScript 和 @observable/plot 中探索和可视化数据。或者使用 deno doc 从您的 JSDoc 注释和源代码生成文档或静态文档网站。

Deno 的特性一览。

我们邀请您今天就尝试 Deno 2,体验 JavaScript 和 TypeScript 开发的未来。现在就开始使用 Deno 2:

加入我们的社区,让我们一起塑造 JavaScript 的未来!