Deno 1.37:在 Jupyter Notebook 中使用现代 JavaScript
Deno 的使命是极大地简化软件开发。在 Deno 1.37 中,我们很高兴将此扩展到交互式的 Jupyter Notebook。从 1.37 开始,您可以使用新的 deno jupyter
命令创建 Deno 内核,该内核可在 Notebook 中使用。此外,Deno 1.37 带来了更强大的 Visual Studio Code 和 LSP 支持、更快的测试性能、改进的 Node 兼容性以及许多错误修复。
如果您已经安装了 Deno,请在您的终端中使用以下命令将其升级到 1.37 版本
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.37 中新增功能的概述。
Deno 1.37 概述
- 📒 Jupyter Notebook Deno 现在与 Jupyter Notebook 完美集成,弥合了脚本和分析之间的差距。
-
🖥️ VSCode 扩展和语言服务器 vscode 扩展继续改进,包括更好地检测
deno.json
,引入deno.disablePaths
配置,更好地支持文件重命名,npm 规范完成,一个名为deno.suggest.completeFunctionCalls
的新配置,以及更多修复。 - 🧪 测试改进 更简单、更快、更好!我们已经改进了我们的测试套件,使编写测试更加直观,并确保更快的反馈循环。
-
⬢ Node.js 兼容性改进 对内置 Node API 的持续改进意味着 Deno 现在支持
npm:mssql
、npm:mineflayer
和npm:web-push
等模块。大多数 NPM 模块可以在 Deno 中开箱即用。 -
🏝️ 生活质量改进 支持新的导入属性语法,使用
Deno.serve()
进行优雅关闭,以及众多性能改进。
Jupyter Notebook 集成
Deno v1.37 附带对 Jupyter Notebook 内核的内置支持,它引入了现代 JavaScript 和 TypeScript,并为数据科学和机器学习带来了全新的可能性。
如果您还没有,请先 安装 Jupyter - 此命令假定您的系统上已安装 Python 和 pip。
pip install jupyterlab
如果您安装了 Python 3,您可能需要使用 pip3
命令。其他安装选项 在此处介绍。
要开始在 Jupyter 中使用 Deno,请运行
deno jupyter --unstable
然后按照提示完成安装。有关 deno jupyter --unstable
的更多文档 在此处。
您现在可以使用 Jupyter Lab 或支持这些 Notebook 的任何您喜欢的 IDE 来创建交互式 REPL 会话。
您可以直接从您的 Notebook 中访问 Deno 的所有 API 以及 npm 模块。
您不仅可以在 Jupyter Notebook 中使用现代 JavaScript,还可以从 npm 导入 D3 来可视化您的数据
此外,您还可以通过返回包含 Symbol.for("Jupyter.display")
函数的对象,从您的单元格中提供丰富的输出
您甚至可以连接到您托管的 Deno KV,使用 Deno KV Connect 将实时数据直接拉入 Notebook
最后,如果您使用的是 Noteable.io,您可以在 您托管的 Jupyter Notebook 中立即使用 Deno。Noteable.io 的首席架构师和 Jupyter 项目的核心维护者 Kyle Kelley 描述了这种集成带来的可能性
Deno 的新 Jupyter 内核为能够编写 JavaScript 的人打开了数据科学工作流的巨大潜力。我对 Deno 的现代 JavaScript 运行时和内置 TypeScript 支持的本机访问带来的可能性感到兴奋。JavaScript 开发人员可以创建 Notebook 来分析数据,构建模型,并创建交互式报告。
使用 Babel 和 TypeScript 配置 Jupyter JavaScript 内核的日子已经一去不复返了。由于 Deno 支持基于 URL 的 ESM 导入,因此 Deno 内核使共享在任何地方运行的 Notebook 变得非常容易。依赖项是声明性的。组织可以利用现有的 Jupyter 部署,并立即获得 Deno 的安全运行时沙箱,而不会放弃 Jupyter 提供的灵活工作流程。
有关使用 Deno 的 Jupyter 集成的更多详细信息,请 查看我们的文档。我们正在寻找社区对该功能的反馈,所以请尝试一下,并 告诉我们您是否发现任何问题或缺少的功能。
VSCode 扩展和语言服务器
deno.json
来启用
通过检测 Deno 扩展默认情况下处于禁用状态,方便在非 Deno TypeScript 项目中工作的用户。以前,您必须在编辑器的 workspace 设置中指定 "deno.enable": true
来启用它。现在,只要您的项目根目录包含 deno.json
文件,您就可以不指定它。您仍然可以指定 "deno.enable": false
来覆盖此设置。
"deno.disablePaths"
为了帮助解决上述情况,引入了一个新的 "deno.disablePaths"
设置。这是对现有 "deno.enablePaths"
设置的补充。如果您有嵌套的非 Deno 子项目,它将禁用 Deno 扩展以针对指定的路径。
// .vscode/settings.json
{
"deno.disablePaths": ["./node_api/", "./vsc_extension/"]
}
自动更新文件重命名时的导入
这是许多语言中广泛使用的重构。Deno 的语言服务器现在提供了此功能 - 重命名 JS/TS 文件后,系统将提示您选择性地更新在整个项目中发现的指向该文件的导入规范。
NPM 规范完成
在导入规范中键入 npm:
URL 时,您现在将看到 NPM 包的自动完成选项。这些选项是通过搜索 NPM 注册表获得的。
import "npm:prea";
// "npm:preact"; ✔️
// "npm:preact-render-to-string";
// "npm:preact-compat";
// "npm:preact-jsx-chai";
// "npm:preact-css-transition-group";
// ...
但可能更有用的是:如果您键入了 npm:<package_name>@
,您将看到该包最新发布版本的自动完成选项。查找有效版本是使用 NPM 规范的繁琐部分。现在,这会为您完成。
import "npm:preact@";
// "npm:[email protected]";
// "npm:[email protected]";
// "npm:[email protected]"; ✔️
// "npm:[email protected]";
// "npm:[email protected]";
// ...
函数调用自动完成
设置 "deno.suggest.completeFunctionCalls": true
,在为已知签名的函数选择自动完成选项时,包含括号和参数占位符。这是对 "typescript.suggest.completeFunctionCalls"
和 "javascript.suggest.completeFunctionCalls"
的重新实现。
// Type the following:
addEventLi
// and select the autocomplete option for `addEventListener`.
// `"deno.suggest.completeFunctionCalls": false`:
addEventListener
// `"deno.suggest.completeFunctionCalls": true`:
addEventListener(type, listener)
deno.cacheOnSave
引入了新的 "deno.cacheOnSave"
设置。启用后,扩展将在您保存文件时自动缓存新的依赖项。这对经常向项目添加新依赖项的用户来说非常方便,无需从命令面板运行“缓存依赖项”命令。目前此设置默认关闭,但我们计划在将来的版本中默认启用它。
测试资源管理器和代码提示修复
自 1.36.0 版本以来,已修复了许多测试 API 错误。
- 测试资源管理器在执行包含步骤的测试时不再冻结。
- 在资源管理器中,当测试步骤名称更改时,测试步骤会被正确替换。之前,每个键入的字符都会注册一个新步骤,您需要重置语言服务器才能清理它。
- 在某些情况下,具有相同名称的嵌套测试步骤不会相互唯一注册,并在资源管理器中共享相同的条目。现在 ID 分配已修复。
- 通过测试资源管理器运行所有测试不再评估不包含任何测试的模块。
- 测试资源管理器不再显示没有测试的模块。
- 通过代码提示运行单个测试,而文件中的另一个测试具有
{ only: true }
,以前不会运行任何测试并记录失败,因为使用了only
选项。现在它按预期行为,并正确忽略其他测试。 - 通过代码提示运行名为
foo
的测试不再运行同一文件中名称包含foo
的其他测试(例如foobar
)。感谢 @Leokuma! - 测试资源管理器中包含的并显示
运行测试
代码提示的文件集现在根据deno.json
字段exclude
、test.exclude
和test.include
进行过滤。
其他修复
- 在自动导入完成条目标签描述中显示源模块。
- 相对和裸规范优先于自动导入完成条目中的远程 URL。
- 插入自动导入代码时,会尊重格式化首选项。
- 不以
.json
结尾的 JSON 模块规范不再显示有关没有默认导出的错误诊断。这会影响数据 URL 和包含查询字符串或片段的规范。 - 快速修复操作按
tsc
、deno
、然后deno-lint
排序。 - 导入完成现在包含本地 JSON 模块。
- 通过完整路径组件匹配
"deno.enablePaths"
条目。以前,以条目为字符串前缀的文件名将被启用(例如,foo
将启用foo.ts
和foobar.ts
)。现在它必须是路径前缀,即条目必须是文件的精确名称或其父目录之一。 - 在调试测试时,始终使用
--inspect-wait
而不是--inspect-brk
。在某些情况下,仍然使用不太合适的--inspect-brk
。感谢 @jeiea! - 正确处理不支持
workspace/configuration
请求的语言服务器客户端。在某些情况下,这些请求被发送到无法处理它们的客户端。 - 删除已废弃的
"deno.testing.enable"
设置。这没有任何作用。
测试改进
继续改进 Deno 的测试 API,从 上次发布 开始,我们这个月也有一些激动人心的更新。
速度改进
我们改进了运行测试的性能,Deno 现在每秒可以运行高达 14,000 个测试。这是通过优化 Deno 测试运行器内置的消毒器实现的,将基线开销从 3 毫秒降低到每个测试用例不到 0.1 毫秒。
我们有进一步改进测试性能的计划,您可以在下一个版本中期待更多速度提升。
TAP
测试报告器
deno test
现在可以以 Test Anything Protocol 格式输出测试结果。您可以使用 --reporter=tap
标志启用它。
$ deno test --reporter=tap ./test.ts
TAP version 14
# ./test.ts
ok 1 - test 0
ok 2 - test 1
ok 3 - test 2
ok 4 - test 3
ok 5 - test 4
ok 6 - test 5
ok 7 - test 6
ok 8 - test 7
ok 9 - test 8
ok 10 - test 9
1..10
感谢 Valentin Anger 实现此功能。
用于聚焦和忽略测试的简写方法
您现在可以使用简写方法 Deno.test.only
和 Deno.test.ignore
来聚焦和忽略测试,如下所示
// Only run this test
Deno.test.only(function myTest() {
// ...
});
// Do not run this test
Deno.test.ignore(function myTest() {
// ...
});
这是一个很小的改变,但比必须指定一个像 Deno.test({ only : true }, function myTest() ...
这样的选项包更容易、更快捷。
生活质量改进
除了上面描述的更改之外,我们还对 Deno 中的测试体验进行了许多其他小的改进。
过滤后的套件不会显示
如果您使用 --filter <name>
标志仅运行一部分测试,测试运行器现在只会在输出中显示过滤后的测试。这使您更容易专注于您关心的测试。
在 Deno v1.37 之前
在 Deno v1.37 中
ASCII 转义字符不再弄乱测试名称
像 \n
、\t
等等的字符现在在测试名称中被正确转义,所以如果你真的需要在测试名称中包含它们,报告器输出就不会被破坏。
--trace-ops
显示更多详细信息
如果您在测试中存在泄漏的操作,--trace-ops
标志可以帮助您找到泄漏的来源。在这个版本中,这个标志变得更加智能,可以在更多情况下显示有用的信息。
only
选项
按名称过滤优先于如果你有一个测试套件,其中only
选项设置为true
,但你想运行一些按名称过滤的测试(使用--filter <name>
标记),该测试将被正确运行。
JUnit 报告包含更多信息
文件、行和列属性被正确添加到生成的报告中。
从覆盖率报告中排除内部代码
通过从生成的报告中排除内部 Deno 代码,覆盖率变得更快、更简洁。
如果你还有其他想法可以改进 Deno 的测试运行器,请在 Deno 的错误追踪器 中提交问题告知我们。
Node.js 兼容性改进
在这个版本中,对 Node.js API 进行了大量非常重要的修复。
child_process
如果环境变量为undefined
或null
,不再抛出错误。crypto
模块实现了 AES GCM 密码。http
现在正确处理Content-Length
头部,发出"error"
事件,正确销毁请求会清理分配的资源。http2
添加了对ClientHttp2Session
和connect
API 的支持。process.title
不再抛出错误。repl._builtinLibs
现在得到支持。tls
现在实现了TLSSocket._start
方法。worker_threads.Worker
现在正确处理process.argv
。zlib
支持dictionary
选项。require
现在使用规范化路径加载内容。- 额外测试和工作的 npm 模块:
mssql
、mineflayer
、infiscal
和web-push
。
如果你想了解更多关于 Deno 中 Node.js 兼容性的信息,请查看 我们的 Node.js 兼容性列表。
生活质量改进
供应商作为缓存覆盖(不稳定)
现在可以通过简单地将以下内容添加到你的deno.json
中来供应商依赖项。
{
"vendor": true
}
下次你运行或缓存(例如deno cache mod.ts
)时,Deno 将使用一个./vendor
文件夹,用该程序使用的远程 https/http 依赖项填充该文件夹。
或者,也可以通过--vendor
标志进行供应商。
请注意,Deno 对./vendor
文件夹的处理方式有所不同,因为并非总是能够将 URL 直接映射到文件系统。
你可能会发现此功能比deno vendor
子命令更容易使用,因为它在管理方面几乎没有开销,并且在更多场景中有效。出于这个原因,deno vendor
子命令可能会从 CLI 中删除,并作为单独的工具发布(有关更多信息,请参阅 问题 #20584)。
导入属性
此版本添加了对 导入属性提案 的支持。该提案以前被称为“导入断言”,Deno 从 1.17 版本开始就支持它。
导入属性允许你使用import
声明导入 JSON 文件。
import jsonData from "./data.json" with { type: "json" };
它也适用于动态导入。
const jsonData = await import("./data.json", { with: { type: "json" } });
使用assert
的旧语法仍然得到支持,但已弃用。我们将在接下来的几个版本中逐步淘汰它;在接下来的版本中,如果你在自己的代码中使用已弃用的assert
语法,Deno 将打印一个警告。
Deno.Server.prototype.shutdown()
此版本带来了一个新的、不稳定的 API:Deno.Server.prototype.shutdown(): Promise<void>
。
// Start a server...
const server = Deno.serve((_req) => new Response("hello world!"));
// ...and close it gracefully after 3 seconds.
setTimeout(async () => {
await server.shutdown();
}, 3000);
在之前的版本中,只能通过使用在构造期间传递给服务器的AbortSignal
来“突然”关闭服务器。然而,并非总是希望以这种方式关闭服务器,在大多数情况下,你希望在关闭服务器之前等待所有正在进行的请求完成。
这个新的 API 是不稳定的,因为我们希望在将其稳定之前从社区收集反馈;此外,我们希望添加一个timeout
参数,它将控制服务器在强制关闭正在进行的请求之前等待多长时间。
性能改进
在这个版本中,我们优化了许多 Web API 以及 HTTP 相关的 API(包括Deno
API 和内置 Node.js API)。以下是完整列表。
Event
和addEventListener
进行了深度优化,使其速度更快;Event.timeStamp
现在始终设置为 0。Headers
针对迭代和查找场景进行了优化,此外还优化了对头部名称的验证。node:http
针对处理头部进行了优化 -IncomingMessageForServer.headers
现在使用缓存,以便在每次访问时不计算头部。node:buffer
从头开始重写,以便在输出字符串时提供更快的结果。node:net
针对套接字读取进行了优化,这使得npm:ws
包的性能更佳。
所有这些优化在 HTTP 基准测试中将 RPS 提高了 10% 以上。
感谢 Marcos Casagrande 实现了其中许多优化。
Lockfile v3
Lockfile 格式已更新到版本 3。Deno 1.37 将在第一次运行时自动将你现有的 lockfile 迁移到新格式,但在 Deno 的旧版本中加载 v3 将会出错。
新格式包含有关重定向的信息,Deno 使用这些信息将 http(s) 重定向锁定到它们在插入 lockfile 时解析到的目标。
std/url
在这个版本中,std/url
模块已添加到 Deno 标准库中。std/url
支持对 URL 执行各种路径操作,这些操作不受 Web 标准 URL 方法或属性 的支持。
目前,std/url
包含以下 5 种方法。
basename
dirname
extname
join
normalize
import {
basename,
dirname,
extname,
join,
normalize,
} from "https://deno.land/[email protected]/std/url/mod.ts";
const url = new URL("https://example.com/home/page.html?foo=bar");
basename(url); // => "page.html"
dirname(url); // => new URL("https://example.com/home")
extname(url); // => ".html"
join("https://example.com", "foo", "bar.html"); // => new URL("https://example.com/foo/bar.html")
normalize("https://example.com///about///page.html"); // => new URL("https://example.com/about/page.html")
感谢 Aritra Karak 实现了这个模块。
std/ulid
在这个版本中,std/ulid
已添加到 Deno 标准库中。std/ulid
支持生成 ULID
和从给定的 ULID 解码时间戳。
import { decodeTime, ulid } from "https://deno.land/[email protected]/ulid/mod.ts";
const id = ulid(); // => "01HARJZ15RFMBVZ1GQ8J4VB6C4"
const timestamp = decode(id); // => 1695189796023
ULID 是 UUID 的替代方案,因为 ULID 的前导部分是从时间戳生成的,所以这些 ID 在生成时间顺序上是按字典顺序排序的。当您将它用作 Deno KV 项目的键的一部分时,此属性非常方便。
感谢 Asher Gomez 建议此功能,并感谢 Lino Le Van 实现它。
V8 11.8 和 TypeScript 5.2.2
最后,Deno v1.37 附带了 V8 11.8 和 TypeScript 5.2.2。
还想了解更多?
信不信由你,上面列出的更改并没有告诉你 1.37 中所有改进的内容。你可以查看在 Deno 1.37 中合并的全部拉取请求列表 在 GitHub 上。
感谢我们的社区贡献者!
没有社区的帮助,我们无法构建 Deno!无论是在我们的社区 Discord 服务器 上回答问题,还是 报告错误,我们都非常感谢您的支持。特别是,我们要感谢以下人士对 Deno 1.37 的贡献:Adam Powers、Alexander Michaud、Curran McConnell、Evan、Fabian、Filip Skokan、Jakub Jirutka、Jonathan Rezende、Juan Gonzalez、Kira、Kyle Kelley、Laurence Rowe、Leigh McCulloch、Marcos Casagrande、Shreyas、Valentin Anger、VlkrS、await-ovo、lionel-rowe、osddeitf、sigmaSd、zuisong、林炳权、第二扩展。
你想加入 Deno 社区贡献者的行列吗?查看我们的贡献文档,下次我们会在列表中看到你。
感谢您关注我们的 1.37 版本发布,希望您喜欢用 Deno 构建!
🍋 您知道吗?Fresh 更新鲜了。
Deno Fresh v1.4 几周前发布,它通过可选的 AOT 编译步骤、异步布局、路由组等功能实现更快的页面加载速度。 了解更多 关于 Deno 的现代 Web 框架的最新版本的信息。