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 候选版本的新特性
- 全局变量
window
和process
的更改 - 依赖管理
- 权限系统更改
- API 更改
- CLI 更改
- 导入断言已死,导入属性万岁
- Node.js 和 npm 兼容性
- 使用
deno test --doc
进行文档测试 - TypeScript 更改
- 致谢
- 下一步是什么?
🚨️ 我们正在积极征求反馈 🚨️
此候选版本帮助我们在最终 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
全局变量,建议改用 globalThis
或 self
。
// 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 错误。
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 始终提供高分辨率计时。
此标志已被弃用,因为可以使用标准的 JavaScript API(如 Worker
和 SharedArrayBuffer
)来实现高分辨率计时。
--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.Reader
和Deno.ReaderSync
Deno.Seeker
和Deno.SeekerSync
Deno.Writer
和Deno.WriterSync
此外,几个与 DNS 记录处理相关的接口已重命名
Deno.CAARecord
toDeno.CaaRecord
Deno.MXRecord
toDeno.MxRecord
Deno.NAPTRRecord
toDeno.NaptrRecord
Deno.SOARecord
toDeno.SoaRecord
Deno.SRVRecord
toDeno.SrvRecord
“资源 ID”在以下 API 中不再可用
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 modules”功能在 Deno v1.38 中引入。
ℹ️ 虽然我们仍然强烈建议不要依赖本地
node_modules
目录,但许多现有项目和框架都基于此目录将存在的假设运行。
但有时您仍然希望拥有本地 node_modules
目录,即使您没有 package.json
- 例如,当使用 Next.js、Remix 或 Svelte 等框架时;或者当依赖于使用 Node-API 的 npm 包时,如 duckdb
、sqlite3
、esbuild
等。为了提高兼容性,如果一个项目包含 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 优先项目的默认模式 - 即没有 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
目录中缺少包的错误,请回退到 auto
或 manual
模式。
Node.js API 兼容性
在受支持的内置 Node.js API 方面再次取得了巨大进展,从而支持了更多流行的软件包
node:crypto
接收了大量更新- 支持 MD4 摘要,修复了
npm:docusaurus
Cipheriv.update(string, undefined)
现在可以正确工作了- 当
autoPadding
选项禁用时,Decipheriv
也是如此 - 现在支持导出 JWK 公钥…
- 导入 EC JWK 密钥也得到了支持…
- 以及导入 JWK octet 密钥对…
- 以及导入 RSA JWK 密钥…
- 最后,支持
npm:web-push
- 支持 MD4 摘要,修复了
async_hooks.AsyncLocalStorage
现在性能更高且更可靠- 现在支持
npm:detect-port
和npm:portfinder
npm:ssh2
获得了更好的支持npm:elastic-apm-node
也是如此node:wasi
现在已被桩接node:events
和node:util
现在具有更好的覆盖率- 由于添加了
FileHandle#writeFile
API 和更好地处理套接字升级,npm:puppeteer
更加可靠 node:constants
、node:fs
、node:path
、node:vm
和node:zlib
导出了缺失的常量node:trace_events
现在已被桩接,并且不会崩溃node:timers
现在导出了promises
符号- 由于修复了
http2
模块,npm:qwik
和npm:hono
更加可靠 - 由于在
child_process
中支持detached
选项,npm:playwright
更加稳定 v8
模块获得了对Serializer
和Deserializer
API 的更好支持,使npm:parcel
可以工作- 以及更多…
deno test --doc
进行文档测试
使用 JSDoc 是一种用于为 JavaScript 和 TypeScript 编写内联文档的格式。 deno doc
和 JSR 自动为其模块生成文档的方式就是使用 JSDoc。
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 中的示例进行类型检查,还会执行它们
要测试您的 JSDoc 示例,只需运行 deno test --doc
,Deno 将自动发现并运行相关的代码块。
ℹ️ 如果您只想对示例进行类型检查,您仍然可以通过运行
deno check --doc
来实现。
但这还不是全部! 除了测试 JSDoc 示例之外,您还可以在 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 issues(带有 2.0 标签)或在 我们 Discord 的专用 #deno-2-help
频道中告知我们。 我们正在积极监控这两个区域,以确保在我们的 2.0 版本发布之前修复所有主要错误。