Deno 1.38:HTML 文档生成器和 HMR
Deno 生态系统持续成熟,在 1.38 版本中,我们很高兴地推出了 deno doc
命令的重大改进。最重要的是,通过新增的 deno doc --html
功能,现在可以生成静态站点文档,这对于希望分享和发布项目文档的开发者来说是一个颠覆性的改变。
如果您已安装 Deno,请在终端中通过以下命令升级到 1.38 版本:
deno upgrade
如果您尚未安装 Deno,可以使用以下任一命令安装,或通过其他多种方式安装。
MacOS / Linux 安装
curl -fsSL https://deno.land/x/install/install.sh | sh
Windows 安装
irm https://deno.land/install.ps1 | iex
以下是 Deno 1.38 中的新增功能概述。
deno doc
改进:新的deno doc --html
命令会为您的项目生成一个包含文档的静态站点。- 模块热替换 (Hot Module Replacement):新的
--unstable-hmr
标志将检测更改,重新加载您的服务器,同时保留状态,让您保持高效生产。 - Node.js 兼容性改进:现在,当您从 Node 迁移时,使用 Deno 变得更加容易,因为您可以使用自己选择的 npm 包管理器。通过
npm
安装 npm 模块,然后用 Deno 运行它。 - 最快 (est) 的 JSX 转换:此版本包含的 JSX 转换速度提高了约 7-20 倍,因为它使用字符串拼接而不是对象分配。我们将深入探讨 JSX 历史,解释我们是如何达到今天的成就的。
deno run --env
:内置支持.env
文件。- WebSockets 改进:支持基于 HTTP/2 的 RFC8841 WebSockets 和多项错误修复。
deno task
支持head
命令- VSCode 扩展和语言服务器:多项生活质量改进
- REPL 中的
Deno.test
支持:与 Jupyter 配合良好。 - Jupyter Notebook 更新:现在支持富 HTML 输出。
Deno
API 更改:Deno.serve
现在支持 Unix 套接字。- Web API 更改:我们添加了
window.name
和EventSource
。 - 标准库更新:最值得注意的是
std/http/server.ts
的弃用。 - 精细的
--unstable-*
标志:更好的内部功能标志。 - 性能改进:当不使用可转移对象时,
structuredClone
现在速度快得多。 - V8 12.0:引入了
Array.fromAsync
和Promise.withResolvers
。
deno doc
更新
本版本在很大程度上借鉴了广受赞誉的 rustdoc,我们自豪地推出了 deno doc
命令的重大增强功能。
最突出的是新的 deno doc --html
命令。这使您能够为您的项目生成一个静态文档站点,比以往任何时候都更容易与您的团队分享见解或在网络上发布。
$ deno doc --html --name="My library" ./mod.ts
Written 11 files to ./docs/
生成的站点提供了库的全面索引和每个导出符号的专用页面。受 rustdoc 索引搜索的启发,客户端符号搜索增强了用户体验。但请放心,即使禁用 JavaScript,该站点也仍能正常运行。
要查看此输出的实际示例,请浏览标准库 fs 模块的生成文档。
对于那些渴望贡献的人,请查看精选问题列表,以帮助提升 Deno 社区的文档体验。
此外,deno doc
已经扩展了其范围。只限制文档生成到一个模块的日子已经一去不复返了。在这个版本中,您可以传递多个入口点,并看着 deno doc
无缝地为每个入口点创建文档。
$ deno doc ./mod.ts other.ts
但是请注意,命令行上的过滤方式略有改变。要指定符号,您现在需要使用 --filter
标志。
此版本中的文档生成也变得更加智能。借助 Rust 中新实现的符号图的力量,它现在能够理解类型和符号之间错综复杂的关系。例如,它现在可以识别导出类型何时使用了私有接口,并相应地调整其输出。
新的 --lint
标志使查找文档中的潜在问题和机会变得更加容易。在生成文档时,它会扫描问题,指出潜在的陷阱并提出补救措施。无论是由于未导出类型、缺少返回类型,还是公共类型缺少 JS 文档注释造成的错误,deno doc --lint
都能为您提供帮助,确保您的文档达到最高水准。
例如,如果您在示例中省略了 : string
返回类型,输出可能看起来像这样:
$ deno doc --lint mod.ts
Type 'getName' references type 'Person' which is not exported from a root module.
Missing JS documentation comment.
Missing return type.
at file:///mod.ts:8:1
error: Found 3 documentation diagnostics.
通过这些检查,deno doc 不仅能帮助您制作出色的文档,还能优化项目中的类型检查。
模块热替换
Deno v1.38 附带了模块热替换功能。模块热替换(HMR)是 JavaScript 开发中的一项功能,它允许您更新和替换应用程序中的模块,而无需完全刷新页面或完全重新启动应用程序。它是改进开发工作流程的宝贵工具。
您可以使用 deno run --unstable-hmr mod.ts
尝试此功能
此标志的功能与 --watch
标志完全相同,但它会尝试就地修补文件,而不是重新启动进程。与 --watch
类似,您可以传递需要监视更改的其他文件。
$ deno run --unstable-hmr=data.json ./mod.ts
请记住,传递给该标志的所有文件仍将导致完整的进程重启;此外,在某些情况下无法就地修补文件(例如,如果您正在更改顶级符号或正在运行的异步函数)。在这种情况下,进程也将进行完全重启。
此功能在各种框架设置中都非常有用——您可能有一个 Deno 编写的后端和前端应用程序,此时能够通知浏览器文件已更改并且浏览器应该重新加载页面就非常有用。为了帮助解决此类情况,您可以以编程方式监听 "hmr"
事件并采取相应行动。
addEventListener("hmr", (e) => {
// `e` is a `CustomEvent` instance and contains `path` property in its
// `detail` field.
console.log("HMR triggered", e.detail.path);
});
Node.js 兼容性改进
为了让 Deno 更容易与 Node.js 项目一起使用,此版本引入了对在 Deno 中使用您选择的 npm 包管理器的不稳定支持。
要试用它,请执行以下命令:
$ mkdir example && cd example
$ npm init -y
$ npm install cowsay
现在创建一个 deno.json 文件来为我们的项目启用 --unstable-byonm
标志
{
"unstable": ["byonm"]
}
以及一个简单的 main.ts 文件
import cowsay from "cowsay";
console.log(cowsay.say({
text: `Hello from Deno using BYONM!``,
}));
现在运行项目
$ deno run main.ts
✅ Granted read access to "node_modules/cowsay/cows/default.cow".
______________________________
< Hello from Deno using BYONM! >
------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
如果我们删除 node_modules
目录,您将看到一个错误,提示我们首先运行 npm install
$ rm -rf node_modules
$ deno run main.ts
error: Could not resolve "cowsay", but found it in a package.json. Deno expects the node_modules/ directory to be up to date. Did you forget to run `npm install`?
at file:///example/main.ts:1:20
当然,我们也可以使用 pnpm
$ pnpm install
$ deno run --allow-read=. main.ts
______________________________
< Hello from Deno using BYONM! >
------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
此功能大大增强了 Deno 与 npm 生态系统的兼容性。为了让 Deno 像 Node 一样开箱即用,无需额外的设置说明,我们正在考虑在即将发布的版本中将其作为默认行为,只要存在 package.json 文件。这将是一个破坏性变更——当前的自动安装行为将变为可选启用而不是可选禁用。有关更多详细信息,请参阅此问题评论,并请在那里分享您的想法。
请注意,如果您在编辑器中使用此功能,则在运行 npm install
或 pnpm install
后,您必须重新启动 Deno 语言服务器,以便获取新的依赖项。我们将在未来的版本中修复此问题。请关注#21042 以获取更新。
如果您想了解更多关于 Deno 中的 Node.js 兼容性信息,请查看我们的 Node.js 兼容性列表。
Node.js 内置模块的裸说明符
在 Deno 中,使用 Node.js 内置模块需要一个 node:
方案
import fs from "node:fs";
console.log(fs);
这在 Node.js 和 Deno 中都有效,但如果您只指定 "fs"
,Deno 就会报错。
> deno run main.ts
error: Relative import path "fs" not prefixed with / or ./ or ../
If you want to use a built-in Node module, add a "node:" prefix (ex. "node:fs").
at file:///main.ts:1:16
从本版本开始,您可以通过使用 --unstable-bare-node-builtins
标志(或在 deno.json 中使用 "unstable": ["bare-node-builtins"]
)来避免此错误。此外,这也适用于 --unstable-byonm
。尽管如此,仍建议为这些说明符添加 node:
方案。
Node.js API 更新
此版本中针对 Node.js API 修复了大量错误
buffer.Buffer.utf8ToBytes
crypto.randomFillSync
http2.ClientHttp2Session
os.availableParallelism
process.argv0
process.version
现在返回node
的 18.18.0 版本tty.ReadStream
tty.WriteStream
uv.errname
最快 (est) 的 JSX 转换
此版本引入了一种新的 JSX 转换,该转换针对服务器端渲染进行了优化。它通过在编译时将 JSX 模板的 HTML 部分序列化为静态字符串数组,而不是创建数百个短生命周期对象来实现。
传统上,JSX 由于其作为浏览器内渲染模板引擎的传承,对垃圾收集器有很大的依赖。
// Input
const a = <div className="foo" tabIndex={-1}>hello<span /></div>
// Output
import { jsx } from "react/jsx-runtime";
const a = jsx(
"div",
{
className: "foo",
tabIndex: -1,
children: [
"hello",
jsx("span", null)
]
}
})
每个元素都会扩展为两个对象分配,元素越多,这个数字增长得越快。
const a = {
type: "div",
props: {
className: "foo",
tabIndex: -1,
children: [
"hello",
{
type: "span",
props: null,
},
],
},
};
新的转换将所有这些工作转移到转译时,并预先序列化 JSX 模板的所有 HTML 部分。
// input
const a = (
<div className="greeting">
<a href={link}>
Hello <b>{name}!</b>
</a>
</div>
);
// output
import { jsxAttr, jsxEscape, jsxTemplate } from "preact/jsx-runtime";
const tpl = ['<div class="greeting"><a ', ">hello <b>", "!</b></a></div>"];
const a = jsxTemplate(tpl, jsxAttr("href", link), jsxEscape(name));
jsxTemplate
函数可以被视为带标签的模板字面量。它在拼接静态字符串数组与动态内容方面具有非常相似的语义。这里需要注意的是,className
已自动转换为 class
,tabIndex
转换为 tabindex
。jsxTemplate
函数没有创建数千个短生命周期的对象,而是在概念上只调用 Array.join()
。只有输出字符串才是一个分配,这使得它非常快。
在我们的测试中,我们观察到渲染时间加快了约 7-20 倍,垃圾收集时间减少了 50%。JSX 的 HTML 部分越多,加速效果越显著。对于组件,我们将在内部退回到传统的 JSX 转换。
此转换特意设计为独立于任何框架。它也不与 Preact 或 Fresh 绑定。通过在 deno.json
中设置自定义 jsxImportSource
配置,您可以将其指向您自己的运行时模块。
{
"compilerOptions": {
"jsx": "precompile",
"jsxImportSource": "custom"
},
"imports": {
"custom/jsx-runtime": "path/to/my/mod.ts"
}
}
自定义 jsx 运行时应导出以下函数:
jsxTemplate(strings, ...dynamic)
jsxAttr(name, value)
jsxEscape(value)
jsx(type, props, key)
deno run --env
一个新的不稳定标志 --env
现在可以用于指定要加载的 .env
文件(例如 --env=.env.dev
),或者在未提供值时加载当前工作目录中的 .env
文件(例如 --env
)。这有一个优势,即无需 --allow-read=.env
权限即可加载 .env
文件。
$ cat .env
MY_ENV_VAR="Loaded!"
$ cat main.js
console.log(Deno.env.get("MY_ENV_VAR"));
$ deno run --env main.js
✅ Granted env access to "MY_ENV_VAR".
Loaded!
我们将在接下来的版本中努力改进此功能,以增加多行变量支持等特性。
WebSockets 改进
WebSockets 实现中修复了大量错误,使得通过安全流发送大型数据包更加可靠,并修复了长时间运行的 WebSocket 流中偶尔出现的死锁。WebSocket 客户端还使用了新的 rustls-tokio-stream crate,这是我们将在 Deno 中逐步推出的新 TLS 实现。
Deno 现在还支持 RFC8441 基于 http/2 的 WebSockets,这适用于仅支持 http/2 并且支持带有 websocket
协议的 http/2 扩展连接协议的服务器。为了与浏览器的行为匹配,任何同时支持 http/1.1 和 http/2 WebSockets 的服务器将继续使用 http/1.1。
deno task
支持 head
命令
deno task
命令现在支持跨平台的 head
命令,它允许您查看文件的开头几行。
{
"tasks": {
"readmeSummary": "head -n 3 README.md"
}
}
$ deno task readmeSummary
# Deno
Deno is a simple, modern and secure runtime for JavaScript and TypeScript that
head
接受单个文件,并支持 -n
/--name
参数来定义要打印的行数。默认情况下,它打印 10 行。
感谢 @dahlia 贡献此功能!
VSCode 扩展和语言服务器
支持 VSCode 内置的 TS/JS 选项
Deno 语言服务器的一些配置选项是对 VSCode 的 typescript-language-features
选项的重新实现。例如:
{
"deno.inlayHints.parameterNames.enabled": "all"
}
现在可以通过其原始键进行切换。以下是受支持选项及其默认值的完整列表:
{
"javascript.inlayHints.enumMemberValues.enabled": false,
"typescript.inlayHints.enumMemberValues.enabled": false,
"javascript.inlayHints.functionLikeReturnTypes.enabled": false,
"typescript.inlayHints.functionLikeReturnTypes.enabled": false,
"javascript.inlayHints.parameterNames.enabled": "none",
"typescript.inlayHints.parameterNames.enabled": "none",
"javascript.inlayHints.parameterNames.suppressWhenArgumentMatchesName": true,
"typescript.inlayHints.parameterNames.suppressWhenArgumentMatchesName": true,
"javascript.inlayHints.parameterTypes.enabled": false,
"typescript.inlayHints.parameterTypes.enabled": false,
"javascript.inlayHints.propertyDeclarationTypes.enabled": false,
"typescript.inlayHints.propertyDeclarationTypes.enabled": false,
"javascript.inlayHints.variableTypes.enabled": false,
"typescript.inlayHints.variableTypes.enabled": false,
"javascript.inlayHints.variableTypes.suppressWhenTypeMatchesName": true,
"typescript.inlayHints.variableTypes.suppressWhenTypeMatchesName": true,
"javascript.preferences.autoImportFileExcludePatterns": [],
"typescript.preferences.autoImportFileExcludePatterns": [],
"javascript.preferences.importModuleSpecifier": "shortest",
"typescript.preferences.importModuleSpecifier": "shortest",
"javascript.preferences.jsxAttributeCompletionStyle": "auto",
"typescript.preferences.jsxAttributeCompletionStyle": "auto",
"javascript.preferences.quoteStyle": "auto",
"typescript.preferences.quoteStyle": "auto",
"javascript.preferences.useAliasesForRenames": true,
"typescript.preferences.useAliasesForRenames": true,
"javascript.suggest.autoImports": true,
"typescript.suggest.autoImports": true,
"javascript.suggest.classMemberSnippets.enabled": true,
"typescript.suggest.classMemberSnippets.enabled": true,
"javascript.suggest.completeFunctionCalls": false,
"typescript.suggest.completeFunctionCalls": false,
"javascript.suggest.enabled": true,
"typescript.suggest.enabled": true,
"javascript.suggest.includeAutomaticOptionalChainCompletions": true,
"typescript.suggest.includeAutomaticOptionalChainCompletions": true,
"javascript.suggest.includeCompletionsForImportStatements": true,
"typescript.suggest.includeCompletionsForImportStatements": true,
"javascript.suggest.names": true,
"typescript.suggest.objectLiteralMethodSnippets.enabled": true,
"javascript.suggest.paths": true,
"typescript.suggest.paths": true,
"javascript.updateImportsOnFileMove.enabled": "prompt",
"typescript.updateImportsOnFileMove.enabled": "prompt"
}
Deno 任务侧边栏视图
类似于 VSCode 内置的 NPM 脚本浏览器,您现在可以在侧边栏视图中浏览 deno.json
中指定的“任务”。
创建一个包含任务定义的 deno.json
文件
{
"tasks": {
"run": "deno run --allow-net --allow-read=. main.ts",
"dev": "deno run --watch --allow-net --allow-read=. main.ts"
}
}
感谢 @ArmaanAS 贡献此功能!
缓存所有依赖项的快速修复
未缓存依赖项的诊断信息已附带一个快速修复选项来缓存该依赖项。现在有一个选项可以缓存包含模块的所有未缓存依赖项。
其他修复和增强功能
- 在悬停 TS 诊断时显示“相关信息”。
- 显示无标题文件的诊断信息。
- 解析远程导入映射。
- 输入
/
时不要提交注册表导入完成。 - 重复调用
Deno: Language Server Status
命令时刷新内容。 - 显示来自未类型化依赖项的类型导入的诊断信息。
- 当删除的文件被重新创建时,使旧的诊断信息失效。
- 修复了编辑器中查看远程模块相关的错误。
- 允许格式化
vendor/
目录中的文件。 - 语言服务器中对 Jupyter Notebook 的初步支持。
- 各种性能改进。
Deno.test
的支持
REPL 中对 此版本为 REPL 带来了 JSX 和 Deno.test
支持。您可以复制粘贴现有测试,它们将直接在 REPL 中运行。
$ deno
> Deno.test("foo", () => {
if (1 !== 2) {
throw new Error("1 !== 2");
}
});
foo ... FAILED (3ms)
ERRORS
foo => <anonymous>:1:27
error: Error: 1 !== 2
at <anonymous>:3:11
FAILURES
foo => <anonymous>:1:27
FAILED | 0 passed | 1 failed (0ms)
同样,您可以复制粘贴现有 JSX 组件以在 REPL 中使用它们。
$ deno
> /** @jsxImportSource https://esm.sh/preact */
undefined
> const test = <h1>Test</h1>
undefined
> test
{
type: "h1",
props: { children: "Test" },
key: undefined,
ref: undefined,
__k: null,
__: null,
__b: 0,
__e: null,
__d: undefined,
__c: null,
__h: null,
constructor: undefined,
__v: -1,
__source: undefined,
__self: undefined
}
此功能也启用了 Jupyter Notebook 中的 JSX 使用!
Jupyter Notebook 更新
Deno.jupyter
命名空间中新增了两个 API:
Deno.jupyter.display
Deno.jupyter.broadcast
您现在可以使用这些 API 在 Jupyter Notebook 中显示富内容并与前端通信。
await Deno.jupyter.display({
"text/plain": "Hello, world!",
"text/html": "<h1>Hello, world!</h1>",
"text/markdown": "# Hello, world!",
}, { raw: true });
await Deno.jupyter.broadcast("comm_msg", {
comm_id: comm_id,
data: {
method: "update",
state: { value: 50, a: null, b: null },
buffer_paths: [["a"], ["b"]],
},
}, {
buffers: [
new TextEncoder().encode("Yay"),
new TextEncoder().encode("It works"),
],
});
感谢 Kyle Kelley 和 Trevor Manz 实现了这些功能。
Deno
API 更改
Deno.serve
Deno.serve
API 新增了对 Unix 域套接字的支持
import { assertEquals } from "https://deno.land/std@0.204.0/assert/mod.ts";
const socketPath = "/tmp/path/to/socket.tmp";
const server = Deno.serve(
{
path: socketPath,
},
(_req, { remoteAddr }) => {
assertEquals(remoteAddr, { path: filePath, transport: "unix" });
return new Response("hello world!");
},
);
此外,Deno.serve
现在返回 Deno.HttpServer
而不是 Deno.Server
。旧的 Deno.Server
类型现已弃用,并将在未来版本中移除。
using
在 Deno API 中使用 Deno v1.37 中随附的 TypeScript 5.2 升级 引入了 using
关键字,该关键字增加了对 显式资源管理提案 的支持。此提案引入了一种便捷的方式来处理执行异步操作的资源。此版本增加了对以下 Deno API 的一次性资源支持:
Deno.Command
Deno.FsFile
Deno.FsWatcher
Deno.HttpConn
Deno.HttpServer
Deno.Kv
Deno.Listener
您现在可以使用 using
关键字在资源超出作用域时自动关闭它们
let kv2: Deno.Kv;
{
using kv = await Deno.openKv(":memory:");
kv2 = kv;
const res = await kv.get(["a"]);
assertEquals(res.versionstamp, null);
// `kv` gets closed here...
}
// ...so it's not usable anymore.
await assertRejects(() => kv2.get(["a"]), Deno.errors.BadResource);
请注意,using
关键字目前仅在 TypeScript 文件中受支持。
Web API 更改
window.name
为了兼容性,我们添加了 window.name
,它是一个空字符串。未来我们可能会考虑设置此值来更改进程名称。
EventSource
EventSource Web API 是一个用于与服务器发送事件交互的客户端,服务器发送事件是一种用于发送事件的单向持久连接。
以下是一个简单的服务器示例,然后使用 EventSource 作为客户端。服务器发送两个事件,客户端记录这两个事件,然后在第二个事件时关闭连接。
// server.ts
import {
ServerSentEvent,
ServerSentEventStreamTarget,
} from "https://deno.land/std@0.204.0/http/server_sent_event.ts";
Deno.serve({ port: 8000 }, (_) => {
const target = new ServerSentEventStreamTarget();
target.dispatchEvent(
new ServerSentEvent("message", {
data: "hello",
id: 1,
}),
);
target.dispatchEvent(
new ServerSentEvent("message", {
data: "world",
id: 2,
}),
);
return target.asResponse();
});
// client.ts
const source = new EventSource("https://:8000");
source.onopen = () => {
console.log("opened");
};
source.onmessage = (e) => {
console.log(`Data for id '${e.lastEventId}':`, e.data);
if (e.lastEventId == 2) {
source.close();
console.log("closed");
}
};
标准库更新
std/path
更新
此版本中新增了 2 个特定于平台的子模块。您现在可以从 std/path/posix
导入 Posix 路径操作,并从 std/path/windows
导入 Windows 路径操作。这两个子模块还具有单个 API 导出路径,例如 std/path/posix/basename.ts
,这在此版本之前是不可用的。
由于上述更改,使用平台特定 API 的旧方法已被弃用。如果您正在使用以下模式,请更新这些导入到新的说明符。
// Old patterns, which are now deprecated
import { posix, win32 } from "https://deno.land/std@0.205.0/path/mod.ts";
import * as posix from "https://deno.land/std@0.205.0/path/posix.ts";
import * as win32 from "https://deno.land/std@0.205.0/path/win32.ts";
// New patterns
import * as posix from "https://deno.land/std@0.205.0/path/posix/mod.ts";
import * as windows from "https://deno.land/std@0.205.0/path/windows/mod.ts";
std/http
更新
http/server
在此版本中已被弃用。请改用 Deno.serve
。
http_errors
、cookie_map
、server_sent_event
、method
现在都带上了 unstable_
前缀。这些模块将在未来重新设计或移除。
std/encoding
更新
hex
、base64
、base64url
、base32
、base58
、ascii85
的 encode
和 decode
方法现已弃用。取而代之的是,这些模块现在导出了 encodeHex
、decodeHex
、encodeBase64
、decodeBase64
等。鼓励用户将现有用法更新为新的 API。
进行此更改的原因是,现有的 encode
和 decode
方法具有多种不同的 API 签名,例如 encode(input: Uint8Array): Uint8Array
、encode(input: Uint8Array): string
、encode(input: ArrayBuffer | string): string
。这些细微的差异很难记住且容易混淆。新的 API 总是使用 encode(input: string | Uint8Array | ArrayBuffer): string
进行编码,以及 decode(input: string): Uint8Array
进行解码。
std/io
模块弃用
std/io
模块已弃用,以劝退使用旧的 Reader
/Writer
接口。现在大多数 I/O 操作都可以通过基于 ReadableStream
的 API 进行访问,这是 Deno 中执行 I/O 的推荐方式。
std/wasi
模块弃用
由于使用率低和社区反馈少,std/wasi
模块已被弃用。如果您仍然需要在 Deno 中使用 WASI,请改用 wasmer-js。
--unstable-*
标志
精细的 您可能已经注意到上述详细信息中引入了以 --unstable-
为前缀的标志。在此版本中,我们实现了一个精细的功能标志系统,以增强我们引入新功能的方式。以前,要激活新功能,必须使用通用的 --unstable
标志。然而,这个标志相当通用——它激活了所有不稳定功能,而没有给用户选择特定功能的选项。
通过此更新,我们提供了一系列标志,使用户能够开启特定的不稳定功能:
--unstable-bare-node-builtins
--unstable-broadcast-channel
--unstable-byonm
--unstable-cron
--unstable-ffi
--unstable-fs
--unstable-hmr
--unstable-http
--unstable-kv
--unstable-net
--unstable-worker-options
如果您只想使用 FFI API,则不必启用所有其他 API,而是可以像这样运行:
$ deno run --allow-read --unstable-ffi main.ts
此外,您现在可以使用 deno.json
配置文件,通过 "unstable"
配置键来决定要激活哪些功能。
{
"unstable": ["byonm", "fs", "kv"]
}
上述配置文件将启用新的“自带 node_modules”功能、不稳定的文件系统 API 以及 Deno KV API。
虽然可以启用所有不稳定功能的 --unstable
标志仍可使用,但我们计划在后续版本中开始发出弃用警告,并建议使用更精确的标志。
性能改进
此版本标志着我们向新的 Rust/v8 快速操作系统 #[op2]
迁移的结束。Deno 中与外部世界交互的每个操作(fetch
、Deno.serve
、Kv
等等)都通过 op 基础设施运行,新版本的 op 系统将使我们能够继续调整性能,特别是对于异步 API。
我们现在可以调整我们 Rust 和 V8 之间发送的每种参数类型的行为,以提取最大性能。我们希望将来能更多地撰写关于 op 接口的博客。请持续关注博客以获取更多信息!
除了新的操作系统,我们还进行了一系列其他性能改进:
由于测试注册和堆栈跟踪收集的改进,
deno test
的启动速度应该会更快。现在创建
DOMException
的成本大大降低。当不使用可转移对象时,
structuredClone
现在速度快得多。
V8 12.0
此版本随 V8 12.0 一起发布,增加了两个令人兴奋的 JavaScript 功能:
例如,Array.fromAsync
与 Deno KV 配合良好
> await Array.fromAsync(kv.list({ prefix: [] }))
[
{
key: [ "foo" ],
value: "bar",
versionstamp: "00000000000000040000"
}
]
感谢我们的贡献者!
没有社区的帮助,我们无法构建 Deno!无论是通过在我们的社区 Discord 服务器中回答问题,还是报告错误,我们都非常感谢您的支持。在此,我们要特别感谢以下对 Deno 1.38 做出贡献的人:Alessandro Scandone, Chen Su, Hirotaka Tagawa / wafuwafu13, Jared Flatow, Jesper van den Ende, Jérôme Benoit, Kenta Moriuchi, Kyle Kelley, Laurence Rowe, Marcos Casagrande, Mark A. Hershberger, Mikhail, Mikko, Rui He, Trevor Manz, sigmaSd, 和 林炳权。
您想加入 Deno 贡献者的行列吗?请在此处查看我们的贡献文档,我们期待下次在列表中见到您。
信不信由你,上面列出的更改仍然没有告诉您 1.38 中所有改进之处。您可以在 GitHub 上查看 Deno 1.38 中合并的完整拉取请求列表。
感谢您关注我们的 1.38 版本,希望您喜欢使用 Deno 进行开发!
🍋 您知道吗?Fresh 变得更加“新鲜”了。
Fresh v1.5 应用 благодаря Partials 的客户端导航、提前转译等功能,变得更快、响应更及时。