宣布 Deno 2
网络是人类最大的软件平台——为其构建意味着可能触达超过 50 亿人。但正如近年来网络开发加速,它也变得越来越难以管理。在编写任何代码之前,开发者必须处理繁琐的配置和浏览不必要的样板代码,而他们更愿意专注于产品发布和为用户提供价值。
然而,尽管存在这些复杂性,JavaScript(网络语言)在过去十年一直是最流行的语言,TypeScript 迅速成为第三大语言。这证明了 JavaScript 在网络开发中的普遍性和实用性——以及 JavaScript 不会消失的迹象。
为了简化网络编程,我们创建了 Deno:一个现代的、一体化的、零配置的 JavaScript 和 TypeScript 开发工具链。
- 原生 TypeScript 支持
- 基于 Web 标准:Promise、fetch 和 ES 模块
- 内置功能:内置格式化程序、代码 linter、类型检查器、测试框架、编译为可执行文件等等
- 默认安全,就像浏览器一样
如今,数十万开发者喜欢使用 Deno,存储库正在成为GitHub 上星标最高的 Rust 项目之一,仅次于 Rust 语言本身。
虽然我们在 Deno 1 中取得了巨大成就,但下一个主要版本专注于大规模使用 Deno。这意味着与传统 JavaScript 基础设施的无缝互操作性,以及对更广泛的项目和开发团队的支持。这一切都无需牺牲 Deno 用户喜欢的简洁性、安全性以及“内置功能”的本质。
今天,我们很高兴地宣布 Deno 2,其中包括
- 与 Node.js 和 npm 的向后兼容性,使您能够无缝运行现有的 Node 应用程序
- 对
package.json
和node_modules
的原生支持 - 使用新的
deno install
、deno add
和deno remove
命令进行包管理 - 稳定的标准库
- 对私有 npm 注册中心的支持
- 工作区和单仓库支持
- 长期支持 (LTS) 版本
- JSR:一个现代的注册中心,用于跨运行时共享 JavaScript 库
我们还在不断改进许多现有的 Deno 功能
deno fmt
现在可以格式化 HTML、CSS 和 YAMLdeno lint
现在具有 Node 特定的规则和快速修复deno test
现在支持运行使用node:test
编写的测试deno task
现在可以运行package.json
脚本deno doc
的 HTML 输出改进了设计和搜索deno compile
现在支持代码签名和 Windows 上的图标deno serve
可以跨多个内核并行运行 HTTP 服务器deno init
现在可以搭建库或服务器deno jupyter
现在支持输出图像、图形和 HTMLdeno bench
支持临界区,以进行更精确的测量deno coverage
现在可以以 HTML 格式输出报告
向后兼容,前瞻性
Deno 2 与 Node 和 npm 向后兼容。这使您不仅可以在当前的 Node 项目中运行 Deno,还可以逐步采用 Deno 的一体化工具链。例如,克隆 Node 项目后,可以使用 deno install
以闪电般的速度安装依赖项,或运行 deno fmt
来格式化代码,而无需 Prettier。
Deno 2 与 Node 和 npm 的兼容性非常强大。Deno 2 了解 package.json
、node_modules
文件夹,甚至 npm 工作区,使您能够使用 ESM 在任何 Node 项目中运行 Deno。如果需要进行少量语法调整,您可以使用 deno lint --fix
修复它们。
不喜欢 package.json
和 node_modules
目录的混乱,但仍然需要使用该 npm 包?您可以使用 npm:
指定符直接导入 npm 包。如果没有 package.json
和 node_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 install
的包管理器
Deno 现在是一个带有 Deno 2 不仅支持 package.json
和 node_modules
文件夹,而且还附带三个重要的子命令,使您能够轻松地安装和管理依赖项。
deno install
以闪电般的速度安装依赖项。如果有一个 package.json
,它会在一瞬间创建 node_modules
文件夹。如果您不使用 package.json
,它会将所有依赖项缓存到全局缓存中。
deno install
比 npm 快 15%,冷缓存速度快 90%,热缓存速度更快。我们在这方面已经非常快了,但在未来几周内,预计会有更多改进,尤其是在冷缓存场景中。
deno add
和 deno remove
可用于向 package.json
或 deno.json
添加和删除包。如果您之前使用过 npm install
或 npm remove
,这些命令会让您感觉非常熟悉。
JavaScript 注册中心
今年早些时候,我们推出了一个现代的开源 JavaScript 注册中心,名为JSR.
它原生支持 TypeScript(您可以将模块发布为 TypeScript 源代码),处理多个运行时和环境的模块加载复杂性,只允许 ESM,从 JSDoc 样式的注释中自动生成文档,并且可以与 npm 和 npx 类似的系统一起使用(是的,JSR 将 TypeScript 转换为 .js
和 .d.ts
文件)。
由于您将 TypeScript 上传到 JSR,因此它对正在发布的代码有很好的了解。这使我们能够为发布和使用模块提供无缝的开发者体验。如果您对细节感兴趣,您可以阅读我们关于如何构建 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
文件,并允许您在没有任何额外配置的情况下拉取私有包。
工作空间和单体仓库
**Deno 2 还支持工作空间,这是一个管理单体仓库的强大解决方案。**只需在您的 deno.json
中使用 workspace
属性列出成员目录
// deno.json
{
"workspace": ["./add", "./subtract"]
}
这些成员可以拥有独立的依赖项、linter 和格式化程序配置等。
Deno 不仅支持 Deno 包的工作空间,还理解 npm 工作空间。这意味着您可以创建混合 Deno-npm 单体仓库 (查看此示例),其中工作空间成员具有 package.json
或 deno.json
。
您还可以通过运行 deno publish
将工作空间成员发布到 JSR。例如,请参考 Deno 标准库。无需手动确定需要以何种顺序发布您的包 - 只需运行 deno publish
,它将为您完成所有操作。
长期支持 (LTS)
通常,大型组织中的开发团队需要仔细审核新版本,然后才能将其用于生产环境。由于 Deno 每周都有错误修复版本发布,以及 6 个每周次要版本发布,这可能会变得很耗时。为了让这些团队更容易使用,**我们推出了一个长期支持 (LTS) 版本发布通道**。
从 Deno 2.1 开始,LTS 通道将接收为期六个月的回溯的关键错误修复,从而确保生产使用的稳定可靠的基础。六个月后,将基于最新的稳定版本创建一个新的 LTS 分支。所有 LTS 版本均可免费获得并根据 MIT 许可证授权,使其可供任何需要更稳定和安全环境的团队使用。
最后,对于需要高级支持的团队,**我们推出了 面向企业的 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 开发的完整工具链以及安全优先的执行模型——所有这些都包含在一个没有外部依赖关系的可执行文件中。与 Node 相比,使用 Deno 可以节省您在安装和配置上的时间,让您更快地开始编码并提供价值。
在运行 Node 程序时,Deno 的选择性权限系统是否会生效?
是的,Deno 的安全优先执行模型适用于运行 Node 程序或导入 npm 模块时,确保相同的安全级别。
为什么是新的 logo?可爱的恐龙吉祥物怎么了?
从一开始,可爱的雨中蜥脚龙就是 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 install
、deno add
和 deno remove
)是可选工具,旨在简化管理依赖项,无论您使用的是 deno.json
还是 package.json
文件。它们对更大、更复杂的项目特别有用,但如果您更喜欢没有配置的简单性,它们不会妨碍您。
我们的核心目标之一是 Deno 可缩放到简单的单文件程序,这些程序可以导入任何包,而无需额外的仪式。例如,在 Jupyter 笔记本或快速脚本等上下文中,您可以轻松地执行以下操作
import * as Plot from "npm:@observablehq/plot";
同时,Deno 可以扩展到处理具有多个文件甚至多个包的 大型项目,例如在单体仓库中。这种灵活性确保 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 fmt
或 deno lint
)。除了改进的包管理、JSR 以及大量针对更高级开发团队的功能外,Deno 已经准备好简化和加速您今天的开发工作。
然而,鉴于 Deno 的巨大功能,我们无法在一篇博客文章和视频中涵盖所有内容。Deno 有很多令人兴奋的功能和用例,我们没有涉及。例如,能够使用 deno compile
将 JavaScript 游戏转换为桌面可执行文件,并支持跨编译(是的,Windows)。或者 Deno 的 Jupyter 笔记本支持,它允许您在 TypeScript 和 @observable/plot 中探索和可视化数据。或者使用 deno doc
从您的 JSDoc 注释和源代码中生成文档或静态文档站点。
我们邀请您今天尝试 Deno 2,体验 JavaScript 和 TypeScript 开发的未来。立即开始使用 Deno 2
加入我们的社区,让我们一起塑造 JavaScript 的未来!