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
命令将为您的项目生成包含文档的静态网站。- 热模块替换: 新的
--unstable-hmr
标志将检测更改,重新加载您的服务器,同时保留状态,让您保持高效。 - Node.js 兼容性改进: 现在,在从 Node 迁移时使用 Deno 变得更加容易,因为现在您可以使用您选择的 npm 包管理器。使用
npm
安装 npm 模块,并使用 Deno 运行它。 - 最快 (est) JSX 转换: 此版本包含 JSX 转换,使用字符串连接而不是对象分配,速度提高了 7-20 倍。我们将深入探讨 JSX 历史,解释我们今天是如何走到这一步的。
deno run --env
: 内置支持.env
文件。- WebSocket 改进: 支持通过 HTTP/2 的 RFC8841 WebSocket 以及许多错误修复。
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 兼容性改进
为了使使用 Node.js 项目尝试 Deno 变得更加容易,此版本引入了对使用您选择的 npm 包管理器与 Deno 的不稳定支持。
要试用它,请执行以下命令
$ 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
最快 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!
我们将致力于在接下来的版本中改进此功能,以添加多行变量支持等功能。
WebSocket 改进
WebSocket 实现中修复了许多错误,使通过安全流发送大型数据包变得更加可靠,并修复了长期运行的 WebSocket 流中偶尔出现的死锁。WebSocket 客户端也使用新的 rustls-tokio-stream crate,这是我们新的 TLS 实现,我们将在 Deno 中逐步推出。
Deno 现在还支持 RFC8441 通过 http/2 的 WebSocket,这在仅广告 http/2 支持的服务器上得到支持,并且支持带有 websocket
协议的 http/2 扩展连接协议。为了与浏览器的行为相匹配,任何支持 http/1.1 和 http/2 WebSocket 的服务器将继续使用 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 笔记本的初步支持。
- 各种性能改进。
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 笔记本中使用 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/[email protected]/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/[email protected]/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://127.0.0.1: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/[email protected]/path/mod.ts";
import * as posix from "https://deno.land/[email protected]/path/posix.ts";
import * as win32 from "https://deno.land/[email protected]/path/win32.ts";
// New patterns
import * as posix from "https://deno.land/[email protected]/path/posix/mod.ts";
import * as windows from "https://deno.land/[email protected]/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 系统将使我们能够继续优化性能,特别是对于异步 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 贡献者的行列吗? 查看我们的贡献文档,我们下次将在列表中见到您。
信不信由你,上面列出的更改仍然没有告诉你 Deno 1.38 中的所有改进。 你可以在 GitHub 上查看 Deno 1.38 中合并的所有拉取请求。
感谢您关注我们的 Deno 1.38 版本,我们希望您喜欢使用 Deno 构建!
🍋 您知道吗? Fresh 变得更加新鲜。
Fresh v1.5 应用程序更加敏捷和响应迅速,这得益于使用 Partials 的客户端导航、提前时间转换等等。