跳至主要内容
Deno 2 终于来了 🎉️
了解更多
Deno 2.0 Release Candidate

Deno 2.0 预览版

更新 2024/10/04: 我们已经发布了几个 Deno 2.0 预览版更新.

我们已经计划了 Deno 的一个新的主要版本多年。很多次,它看起来即将发布,但我们意识到我们想要的功能需要更多工作。现在,它终于要发布了。上个月,我们发布了最后的 1.x 版本,1.46,而今天,我们发布了 Deno 2.0 的预览版,其中包含了我们预计在最终版本中包含的所有内容。这是自 1.0 以来最大的更新,包含了重大变化,例如引入了 Node 的 process 全局变量。我们也做了一些哲学上的转变,例如更喜欢 deno install 而不是现在已弃用的 deno cache。继续阅读以了解更改的完整列表,并 分享您的反馈

要尝试预览版,请在您的终端中运行以下指令

deno upgrade
deno upgrade rc

ℹ️ 如果你使用的是像 Homebrew 这样的替代分发方法,deno upgrade 可能不可用。

按照 https://deno.org.cn 上的安装说明进行操作,然后运行上述命令。

Deno 2.0 预览版的新功能

🚨️ 我们正在积极寻求反馈 🚨️

此预览版帮助我们在最终 2 版本发布之前识别问题。如果您遇到任何问题或需要额外的指导,请 在 GitHub 上创建一个 issue 或在 我们 Discord 的 #deno-2-help 频道 中提问。我们的团队正在积极监控这两个地方,并将尽快提供帮助。

全局变量更改

Deno 2 带来了两个关于全局变量的主要更改 - window 不再存在,而 Node 的 process 现在可用。


我们在 Deno v1.0 中引入了 window 全局变量,目标是使 Deno 尽可能与浏览器兼容。不幸的是,window 全局变量成为了用户问题的根源。

许多库通过探测 window 全局变量来检查它们是否在浏览器中执行,而不是检查 DOM 的存在。这导致了库中的一类错误,而这些错误原本可以在 Deno 中正常工作,因为 window 是全局可用的。

Deno 开始 在 v1.40 中不鼓励使用 window 全局变量,建议使用 globalThisself 来代替。

// Deno v1.x
window.addEventListener("load", () => {
  console.log("loaded");
});

// Deno v2.x
globalThis.addEventListener("load", () => {
  console.log("loaded");
});

相反,process 全局变量一直被广泛请求。

虽然长期以来一直可以通过从 node:process 模块导入它来使用 process,但许多流行的框架依赖于它在全局范围内的存在,通常用在配置文件中。

虽然添加 import process from 'node:process'; 看起来很简单,但它经常会导致用户使用原本可以在 Deno 中无缝运行的流行框架时产生摩擦。

因此,随着 process 全局变量的添加,您可以预期更多最初为 Node.js 编写的代码能够在 Deno 中无更改地运行。但是,我们仍然鼓励用户更喜欢显式导入。因此,添加了一个新的 no-process-global lint 规则,该规则将在您的编辑器中提供提示和快速修复,以便使用导入语句来代替。

依赖项管理

Deno 2 带来了几个新功能,改进依赖项管理。

deno add 子命令现在可以处理带子路径的规范符

# Before in Deno v1.46
deno add jsr:@std/testing/snapshot
error: Failed to parse package required: @std/testing/snapshot

Caused by:
    0: Invalid package requirement '@std/testing/snapshot'. Invalid version requirement. Invalid specifier version requirement. Unexpected character '/'
    ...

# Deno v2.0
deno add jsr:@std/testing/snapshot
Add jsr:@std/[email protected]

# Deno v1.46
deno add npm:preact/hooks
error: Failed to parse package required: npm:preact/hooks

Caused by:
    0: Invalid package requirement 'preact/hooks'. Packages in the format <scope>/<name> must start with an '@' symbol.
    1: Packages in the format <scope>/<name> must start with an '@' symbol.

# Deno v2.0
deno add npm:preact/hooks
Add npm:[email protected]

ℹ️ 使用 jsr:npm: 前缀现在是必需的,以避免在两个注册表中同名包之间潜在的歧义。

如果省略了前缀,Deno 将打印一个建议,并使用正确的调用方式,检查哪个注册表包含该包。

此外,如果您的项目包含 package.json 文件,Deno 将更倾向于将 npm: 依赖项添加到 package.json 中,而不是 deno.json 中。

cat package.json
{
  "dependencies": {}
}

deno add npm:express
Add npm:[email protected]

cat package.json
{
  "dependencies": { "express": "^5.0.0" }
}

您还可以使用 --dev 标志将“开发依赖项”添加到 package.json

deno add --dev npm:express
Add npm:[email protected]

cat package.json
{
  "devDependencies": { "express": "^5.0.0" }
}

deno install 现在支持 --entrypoint 标志,它允许您从给定的模块安装所有依赖项

// main.ts
import snapshot from "jsr:@std/testing/snapshot";
import express from "npm:express";
deno install --entrypoint main.ts
Download ...

添加了一个新的 deno remove 子命令,用于快速删除一些依赖项

deno add jsr:@std/testing
Added jsr:@std/[email protected]

cat deno.json
{
  "imports": { "@std/testing": "jsr:@std/testing@^1.0.2" }
}

deno remove @std/testing
Removed @std/testing

cat deno.json
{}

您还可以使用 deno remove 来处理 package.json 中列出的依赖项。


Deno 2 附带了一个新的、更简洁的锁文件格式 (v4),它将最大限度地减少更新依赖项时的差异并确保可重复构建。

cat deno.lock
{
  "version": "4",
  "specifiers": {
    "jsr:@std/assert@^1.0.4": "1.0.5",
    "jsr:@std/data-structures@^1.0.2": "1.0.4",
    "jsr:@std/fs@^1.0.3": "1.0.3",
    "jsr:@std/internal@^1.0.3": "1.0.3",
    "jsr:@std/path@^1.0.4": "1.0.6",
    "jsr:@std/testing@*": "1.0.2",
    "jsr:@std/testing@^1.0.2": "1.0.2"
  },
  // ...
}

Deno 将自动将您迁移到新的锁文件格式。


最后,Deno 改进了其错误消息,为常见问题提供了有用的提示,例如格式不正确的相对导入路径,或在使用“裸规范符”时缺少依赖项

// main.ts
import "@std/dotenv/load";
deno run main.ts
error: Relative import path "@std/dotenv/load" not prefixed with / or ./ or ../
  hint: Try running `deno add jsr:@std/dotenv/load`
    at file:///main.ts:1:8

这些更新共同简化了在 Deno 项目中管理依赖项的过程,使其更直观,并与现代开发工作流程保持一致。

权限系统更改

新的 Deno.errors.NotCapable 错误

Deno 的权限系统是其最受欢迎的功能之一。当程序尝试访问未经 --allow-* 标志允许的 API 时,会引发错误。在 Deno v1.x 中,这是 Deno.errors.PermissionDenied

但这有一个问题。所有操作系统也会引发这个错误,例如,当您的用户没有访问管理员专用文件的权限,或者当您试图监听一个特权端口时。因此,用户经常会感到困惑,因为即使使用 --allow-all 标志,也会看到此错误被引发。

在 Deno v2.0 中,缺少 Deno 权限现在会引发 Deno.errors.NotCapable 错误,而不是 Deno.errors.PermissionDenied,以便更轻松地区分操作系统级错误和 Deno 错误。

await Deno.readTextFile("./README.md");

Deno v1.46

$ deno run main.ts
error: Uncaught (in promise) PermissionDenied: Requires read access to "./README.md", run again with the --allow-read flag
await Deno.readTextFile("./README.md")
           ^
    at Object.readTextFile (ext:deno_fs/30_fs.js:878:24)
    at file:///main.ts:1:12

Deno v2.0

$ deno run main.ts
error: Uncaught (in promise) NotCapable: Requires read access to "./README.md", run again with the --allow-read flag
await Deno.readTextFile("./README.md")
           ^
    at Object.readTextFile (ext:deno_fs/30_fs.js:777:24)
    at file:///main.ts:1:12

Deno.mainModule 不需要 --allow-read 权限

Deno.mainModule API 的权限检查(它为您提供主模块的完整路径)已放宽,不再需要完全的 --allow-read 权限。这也适用于 process.argv API。

此要求已弃用,但可以通过创建 Error 实例并检查其堆栈跟踪来获取主模块的路径。

--allow-hrtime 标志已移除

Deno v1.x 具有 --allow-hrtime 标志,它影响 performance.now() 等 API,提供高分辨率计时。在 Deno 2 中,此标志已移除,这些 API 始终提供高分辨率计时。

此标志已弃用,因为可以使用 WorkerSharedArrayBuffer 等标准 JavaScript API 来实现高分辨率计时。

--allow-run 标志更改

对于 --allow-run 标志,我们进行了一些重大更改,旨在帮助您更安全地执行子进程。

首先,如果您在没有指定二进制文件名称或二进制文件路径的允许列表的情况下使用 --allow-run 标志,将会出现警告。

new Deno.Command("echo", { args: ["hello"] }).spawn();
$ deno run --allow-run main.ts
Warning --allow-run without an allow list is susceptible to exploits. Prefer specifying an allow list (https://docs.deno.org.cn/runtime/fundamentals/security/#running-subprocesses)
hello

然后,每当使用 LD_*DYLD_* 环境变量生成子进程时,将需要完整的 --allow-run 权限。请注意,这些环境变量应很少依赖。如果您确实需要使用它们,则应考虑通过运行额外的保护层(例如 Docker 容器)来进一步沙箱化 Deno。

new Deno.Command("echo", {
  env: {
    "LD_PRELOAD": "./libpreload.so",
  },
}).spawn();
$ deno run --allow-run=echo main.ts
error: Uncaught (in promise) NotCapable: Requires --allow-all permissions to spawn subprocess with LD_PRELOAD environment variable.
}).spawn();
   ^
    at spawnChildInner (ext:runtime/40_process.js:182:17)
    at spawnChild (ext:runtime/40_process.js:205:10)
    at Command.spawn (ext:runtime/40_process.js:479:12)
    at file:///main.ts:5:4

在文件名中转义逗号

现在可以授予对包含逗号的文件名的文件进行读写权限。

在 Deno v1.x 中,使用逗号分隔多个文件名。

deno run --allow-read=file1.txt,file2.txt
# grants permission to read `file1.txt` and `file2.txt`

这使得无法授予对文件名中包含逗号的文件的权限。

在 Deno 2 中,可以通过使用另一个逗号转义逗号来实现这一点。

deno run --allow-read=file,,.txt,file2.txt
# grants permission to read `file,.txt` and `file2.txt`

API 更改

稳定 API

在此 Deno 2 中,一些 API 已稳定。

  • WebGPU API 不再需要 --unstable-webgpu 标志。
  • Deno.dlopen() 和其他 FFI API 不再需要 --unstable-ffi 标志。
  • Deno.createHttpClient() 不再需要 --unstable-http 标志。

错误消息也得到了改进,在您尝试在没有相应标志的情况下使用不稳定 API 时,会提供有用的提示。

const db = await Deno.openKv();

Deno v1.46

$ deno run db.ts
error: Uncaught (in promise) TypeError: Deno.openKv is not a function
const db = await Deno.openKv();
                      ^
    at file:///db.ts:1:23

Deno v2.0

error: Uncaught (in promise) TypeError: Deno.openKv is not a function
const db = await Deno.openKv();
                      ^
    at file:///db.ts:1:23

    info: Deno.openKv() is an unstable API.
    hint: Run again with `--unstable-kv` flag to enable this API.

Deno API 的重大更改

ℹ️ 有关如何迁移到弃用 API 的更多信息,请访问 Deno 1 到 2 迁移指南

以下 API 已被移除

  • Deno.Buffer
  • Deno.close()
  • Deno.copy()
  • Deno.customInspect
  • Deno.fdatasync()Deno.fdatasyncSync()
  • Deno.File(此外,Deno.FsFile 也不能再手动构造)
  • Deno.flock()Deno.flockSync()
  • Deno.fstat()Deno.fstatSync()
  • Deno.fsync()Deno.fsyncSync()
  • Deno.ftruncate()Deno.ftruncateSync()
  • Deno.funlock()Deno.funlockSync()
  • Deno.futime()Deno.futimeSync()
  • Deno.iter()Deno.iterSync()
  • Deno.metrics()
  • Deno.read()Deno.readSync()
  • Deno.readAll()Deno.readAllSync()
  • Deno.resources()
  • Deno.seek()Deno.seekSync()
  • Deno.shutdown()
  • Deno.write()Deno.writeSync()
  • Deno.writeAll()Deno.writeAllSync()

TLS 选项的处理已更新,以下选项不再受支持

  • Deno.ConnectTlsOptions.certChain
  • Deno.ConnectTlsOptions.certFile
  • Deno.ConnectTlsOptions.privateKey
  • Deno.ListenTlsOptions.certChain
  • Deno.ListenTlsOptions.certFile
  • Deno.ListenTlsOptions.keyFile

以下接口已被移除

  • Deno.Closer
  • Deno.ReaderDeno.ReaderSync
  • Deno.SeekerDeno.SeekerSync
  • Deno.WriterDeno.WriterSync

此外,与 DNS 记录处理相关的几个接口已重命名

  • Deno.CAARecordDeno.CaaRecord
  • Deno.MXRecordDeno.MxRecord
  • Deno.NAPTRRecordDeno.NaptrRecord
  • Deno.SOARecordDeno.SoaRecord
  • Deno.SRVRecordDeno.SrvRecord

以下 API 中不再提供“资源 ID”。

  • Deno.FsWatcher.prototype.rid
  • Deno.Conn.prototype.rid
  • Deno.TlsConn.prototype.rid
  • Deno.TcpConn.prototype.rid
  • Deno.UnixConn.prototype.rid
  • Deno.FsFile.prototype.rid
  • Deno.Listener.prototype.rid
  • Deno.TlsListener.prototype.rid

最后,一些 API 已被“软弃用”。这些 API 将继续工作,但将不再接收更新或错误修复。强烈建议并鼓励您迁移到稳定的对应项。

  • Deno.serveHttp() - 使用 Deno.serve() 代替
  • Deno.run() - 使用 new Deno.Command() 代替
  • Deno.isatty(Deno.stdin.rid) - 使用 Deno.stdin.isTerminal() 代替
  • Deno.isatty(Deno.stdout.rid) - 使用 Deno.stdout.isTerminal() 代替
  • Deno.isatty(Deno.stderr.rid) - 使用 Deno.stderr.isTerminal() 代替

命令行界面更改

Deno 2 移除对两个子命令的支持

  • deno bundle - 此子命令 在 Deno v1.31 中已弃用,因为用户期望与内置捆绑程序提供的实际功能不符。

    许多 Deno 用户期望一个通用的、高度可定制的捆绑程序。但是 Deno 的内置捆绑程序旨在作为一个简单的工具,将多个文件连接到一个文件中,以便于分发;也不存在任何设置来定制任何行为。

    我们计划实施一个新的内置捆绑程序,请关注未来版本的更新。

  • deno vendor - 在 Deno v1.45 中已弃用,并被使用 在 Deno v1.37 中引入的 deno.json 文件中的 vendor 选项 的更简单的解决方案取代。

一些 CLI 标志现在已弃用

  • --lock-write - 使用 --frozen 代替
  • --unstable - 使用更细粒度的 --unstable-<feature> 标志代替
  • test --allow-none - 使用 test --permit-no-files
  • --jobs - 使用 DENO_JOBS 环境变量代替
  • test --trace-ops - 使用 test --trace-leaks
  • --ts - 使用 --ext=ts 代替

此外,您可以使用 DENO_LOG 环境变量启用调试日志记录,而不是 RUST_LOG

最后,配置文件中的 files 选项现在已弃用。

在 Deno v1.x 中,支持此语法

{
  "test": {
    "files": {
      "include": ["**/*.ts"],
      "exclude": ["ignore.ts"]
    }
  }
}

在 Deno 2 中,files 配置已简化,并被扁平化为父配置。

{
  "test": {
    "include": ["**/*.ts"],
    "exclude": ["ignore.ts"]
  }
}

导入断言已死,长存导入属性

导入断言支持 在 Deno v1.46 中已弃用,在 Deno 2 中不再可用。

原因是,该提案已发生了重大变化,包括将关键字从 assert 更新为 with,并更名为 导入属性,此外一些浏览器(例如 Chrome)也已取消了对导入断言的支持。

以下是更新内容

- import data from "./data.json" assert { type: "json" };
+ import data from "./data.json" with { type: "json" };

Node.js 和 npm 兼容性

改进的 CommonJS 支持

自 1.0 版本发布以来,Deno 一直将 ES 模块作为主要模块系统,仅通过手动创建 require 来提供对 CommonJS 的有限支持。

import { createRequire } from "node:module";
const require = createRequire(import.meta.url);
require("...");

虽然我们坚信 ES 模块是 JavaScript 的未来,但 2024 年的现状仍然包括大量依赖 CommonJS 的库和项目。

尽管 Deno 在过去一年中对 CJS 库进行了强大的处理,但用户在集成 CommonJS 时,尤其是与其自身代码库集成时,偶尔会遇到挑战。

在 Deno 2 中,进行了一些改进,以帮助使用 CommonJS 模块并使迁移到 ES 模块更加容易。

  • deno run index.cjs - Deno 现在可以执行 CommonJS 文件,前提是它们使用 .cjs 扩展名。Deno 不会查找 package.json 文件和 type 选项来确定文件是 CommonJS 还是 ESM。

    使用此选项时,Deno 也不会自动安装依赖项,因此您需要提前手动运行 deno install 以确保所有必需的依赖项可用。

// index.cjs
const express = require("express");

注意: Deno 权限系统仍然有效,因此 require() 调用将提示 --allow-read 权限。

deno run index.cjs
┏ ⚠️  Deno requests read access to "/dev/example".
┠─ Learn more at: https://docs.deno.org.cn/go/--allow-read
┠─ Run again with --allow-read to bypass this prompt.
┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions) >
  • import cjs from "./index.cjs" - Deno 现在可以导入 CommonJS 文件,前提是它们使用 .cjs 扩展名。Deno 不会查找 package.json 文件和 type 选项来确定文件是 CommonJS 还是 ESM。
// greet.cjs
module.exports = {
  hello: "world",
};
import greet from "./greet.cjs";
console.log(greet);
deno run main.js
{
  "hello": "world"
}
  • require(ESM) - Deno 现在支持 require ES 模块。只有在所需的模块不使用顶层 Await 时才有可能。此更改应在使用依赖于 CommonJS 和 ESM 的混合依赖项时提高互操作性。
// greet.js
export function greet(name) {
  return `Hello ${name}`;
}
// esm.js
import { greet } from "./foo.js";

export { greet };
// main.cjs
const esm = require("./esm");
console.log(esm);
console.log(esm.greet("Deno"));
deno run --allow-read main.cjs
[Module: null prototype] { greet: [Function: greet] }
Hello Deno
  • 在处理 CommonJS 模块时,针对错误的更佳建议,可以引导您找到一个可运行的程序
// main.js
module.exports = {
  foo: "foo",
};
deno run main.js
error: Uncaught (in promise) ReferenceError: module is not defined
module.exports = {
^
    at file:///Users/ib/dev/deno/main.js:1:1

    info: Deno does not support CommonJS modules without `.cjs` extension.
    hint: Rewrite this module to ESM or change the file extension to `.cjs`.

自带 node_modules 是默认值

“自带 Node 模块”功能 是在 Deno v1.38 中引入的.

ℹ️ 虽然我们仍然强烈建议不要依赖本地 node_modules 目录,但许多现有项目和框架都假设此目录存在。

但有时您仍然希望拥有本地 node_modules 目录,即使您没有 package.json - 例如,当使用 Next.js、Remix 或 Svelte 等框架时;或者当依赖于使用 Node-API 的 npm 包时,例如 duckdbsqlite3esbuild 等。为了提高兼容性,如果项目包含 package.json 文件,Deno 将期望 node_modules 目录已手动设置。


在之前的 Deno 版本中,您可以使用 --node-modules-dir 标志或配置文件中的 nodeModulesDir 选项来告诉 Deno 是否应该创建 node_modules 目录。

Deno 2 更改了此配置选项 - 它不再是布尔值,而是具有三个选项的枚举

默认模式

deno run main.ts

# or

deno run --node-modules-dir=none main.ts

或使用配置文件

{
  "nodeModulesDir": "none"
}

这是 Deno-first 项目的默认模式 - 也就是说,没有 package.json 文件的项目。它会自动将依赖项安装到全局缓存中,并且不会创建本地 node_modules 目录。

ℹ️ 推荐 用于新项目。请注意,期望 node_modules 目录的框架将无法正常工作,此外还包括任何依赖于 postinstall 脚本的 npm 依赖项。

auto 模式

deno run --node-modules-dir=auto main.ts

或使用配置文件

{
  "nodeModulesDir": "auto"
}

auto 模式会自动将依赖项安装到全局缓存中,并在项目根目录中创建一个本地 node_modules 目录。

ℹ️ 推荐 用于具有依赖于 node_modules 目录的 npm 依赖项的项目 - 主要是一些使用打包工具的项目,或者具有 postinstall 脚本的 npm 依赖项的项目。

manual 模式

deno run --node-modules-dir=manual main.ts

或使用配置文件

{
  "nodeModulesDir": "manual"
}

manual 模式是使用 package.json 的项目的默认模式。此模式是 Node.js 使用的工作流程,需要使用 deno install/npm install/pnpm install 或任何其他包管理器进行显式安装步骤。

ℹ️ 推荐 用于使用 Next.js、Remix、Svelte、Qwik 等框架的项目;或使用 Vite、Parcel、Rollup 等工具的项目。


建议使用默认的 none 模式,如果您遇到有关 node_modules 目录中缺少包的错误,请回退到 automanual 模式。

Node.js API 兼容性

再次强调,在支持的内置 Node.js API 方面取得了重大进展,导致更多流行的包得到支持

使用 deno test --doc 进行文档测试

JSDoc 是一种用于为 JavaScript 和 TypeScript 编写内联文档的格式。这是 deno docJSR 自动为其模块生成文档 的方式。

JSDoc 允许我们直接在注释中编写代码示例

/**
 * ```ts
 * import { assertEquals } from "jsr:@std/assert/equals";
 *
 * assertEquals(add(1, 2), 3);
 * ```
 */
export function add(a: number, b: number) {
  return a + b;
}

不过,这里有一个问题... 如何确保这些示例保持最新,并且不会出现代码腐烂问题?

Deno v1.10 添加了对示例进行类型检查的功能,这有助于解决问题,但没有完全解决。确保示例保持最新的唯一方法是实际执行它们。

在 Deno 2 中,deno test --doc 不仅会对 JSDoc 中的示例进行类型检查,还会执行它们

在 Deno 2 中测试 JSDoc 示例的演示

要测试您的 JSDoc 示例,只需运行 deno test --doc,Deno 将自动发现并运行相关的代码块。

ℹ️ 如果您只想对示例进行类型检查,您仍然可以通过运行 deno check --doc 来实现。

但这还不是全部!除了测试 JSDoc 示例之外,您还可以执行 Markdown 文件中的代码块

在 Deno 2 中测试 Markdown 代码块的演示

这是此功能的第一个版本,我们 欢迎任何反馈.

TypeScript 更改

Deno v2.0 附带 TypeScript 5.6,您可以在 Announcing TypeScript 5.6 博客文章中详细了解它。

为了帮助捕获常见的陷阱,这些 TypeScript 设置现在默认启用

此外,Deno 2 附带对版本 22 的 @types/node 的内置支持,这使得对依赖于 Node.js API 的代码进行类型检查变得更加容易。

最后,为了确保您的 compilerOptions 设置是最新的,我们将其设置为允许列表,因此,如果您使用不支持的选项,Deno 会报错并将其标记出来。

致谢

没有社区的帮助,我们就无法构建 Deno!无论是回答我们社区 Discord 服务器 中的问题,还是 报告错误,我们都对您的支持表示衷心的感谢。特别感谢以下人员对 Deno 2 发布候选版本的贡献:Andreas Deininger、Armaan Salam、Bedis Nbiba、Birk Skyum、Bob Callaway、Caleb Cox、Caleb Lloyd、Coty、Hajime-san、HasanAlrimawi、Ian Bull、Ivancing、Jake Abed、Kamil Ogórek、Kenta Moriuchi、Kyle Kelley、Mohammad Sulaiman、MrEconomical、MujahedSafaa、Pig Fang、Rano | Ranadeep、Roy Ivy III、Sean McArthur、Sʜɪᴍᴜʀᴀ Yū、Victor Turansky、Yazan AbdAl-Rahman、Zebreus、chirsz、cions、i-api、melbourne2991、seb、vwh 以及 Łukasz Czerniawski。

您想加入 Deno 贡献者行列吗?请查看我们的贡献文档,我们期待下次在名单上看到您。

感谢您关注我们的 Deno 2 发布候选版本,我们希望您喜欢使用 Deno 进行构建!

下一步是什么?

这个发布候选版本正在为我们的 2.0 版本做准备,预计会有一些错误和问题。如果您遇到任何问题,请在 GitHub 问题(使用 2.0 标签)或 我们 Discord 上的专用 #deno-2-help 频道 中告知我们。我们正在积极监控这两个区域,以确保在 2.0 版本发布之前修复所有主要错误。