首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Deno 1.8 正式发布:附带完整的 ICU 支持;deno lsp 和导入映射均已稳定

Deno 1.8 现已正式发布,快来看看有哪些新特性!

今天我们发布了 Deno 1.8.0。这一版本包含大量的新特性和稳定改进:

  • 对 WebGPUAPI 的实验性支持:为在 Deno 中开箱即用的 GPU 加速机器学习铺平道路
  • 启用内置的国际化 API:所有 JSIntlAPI 都可以直接使用
  • 改进的覆盖率工具链:覆盖率现在支持输出 lcov 报告
  • 导入映射现已稳定:现已发布与 Web 兼容的依赖重写
  • 支持获取私有模块:使用身份验证令牌从私有服务器获取远程模块

如果你已经安装了 Deno,则可以运行 deno upgrade 来升级到 1.8。如果你是第一次安装 Deno,则可以使用下面列出的方法之一:

代码语言:javascript
复制
# Using Shell (macOS and Linux):
curl -fsSL https://deno.land/x/install/install.sh | sh
# Using PowerShell (Windows):
iwr https://deno.land/x/install/install.ps1 -useb | iex
# Using Homebrew (macOS):
brew install deno
# Using Scoop (Windows):
scoop install deno
# Using Chocolatey (Windows):
choco install deno

新特性与更改

对 WebGPU API 的实验性支持

WebGPU API 为开发人员提供了一种低级、高性能、跨架构的方法,可以使用 JavaScript 语言来编程 GPU 硬件。它是 Web 上的 WebGL 的有力继承者。它的规范尚未最终确定,但人们已为 Firefox、Chromium 和 Safari 添加了支持,如今 Deno 也跟上了脚步。

通过这一 API,你可以直接从 Deno 内部访问 GPU 渲染和通用 GPU 计算能力。该特性完成、稳定和取消标志后,将提供一种可移植的方式来从 Web、服务器和开发人员机器访问 GPU 资源。

GPU 使程序员可以让某些数值算法高度并行化。除了渲染图形和游戏外,它还有很大的用武之地。在机器学习中深度应用的 GPU 已经带来了更复杂的神经网络——也就是所谓的深度学习。计算机视觉、翻译、图像生成、强化学习等领域的飞速发展都源于 GPU 硬件的高效利用。

如今,大多数神经网络都是用 Python 定义的,而计算由 GPU 负责。我们相信,如果存在适当的基础架构,JavaScript(而不是 Python)可以用作表达数学思想的理想语言。在 Deno 中提供现成的 WebGPU 支持是朝这个方向迈出的一步。我们的目标是通过 GPU 加速在 Deno 上运行 Tensorflow.js。我们预计这将在未来几周或几个月内实现。

下面是一个基本示例,演示了如何访问系统连接的 GPU 设备以及读取名称和支持的功能:

代码语言:javascript
复制
// Run with `deno run --unstable https://deno.land/posts/v1.8/webgpu_discover.ts`
// Try to get an adapter from the user agent.
const adapter = await navigator.gpu.requestAdapter();
if (adapter) {
// Print out some basic details about the adapter.
console.log(`Found adapter: ${adapter.name}`);
const features = [...adapter.features.values()];
console.log(`Supported features: ${features.join(", ")}`);
} else {
console.error("No adapter found");
}

下面是一个小示例,演示了 GPU 使用渲染着色器在绿色背景上渲染一个简单的红色三角形:

代码语言:javascript
复制
$ deno run --unstable --allow-write=output.png https://raw.githubusercontent.com/crowlKats/webgpu-examples/f3b979f57fd471b11a28c5b0c91d0447221ba77b/hello-triangle/mod.ts

注意使用 WebAssembly 编写的 PNG。有关更多示例,请访问以下存储库:

https://github.com/crowlKats/webgpu-examples

最终的 PR 占用了多达 15.5 万行代码,并且在打开后花了整整 5 个月的时间合并。非常感谢 crowlKats 领导了将 WebGPU 集成到 Deno 中的工作。我们还要感谢为 Deno 中的 WebGPU 实现奠定基础的 wgpu 和 gfx-rs 项目的所有贡献者。特别感谢 WebGPU 规范的编辑 kvark 以及 wgpu 和 gfx-rs 的首席开发人员,他们为实现 WebGPU API 提供了出色的指导。

ICU 支持

在 Deno 存储库中,ICU 支持已成为需求第二大的特性。我们很高兴地宣布 Deno v1.8 附带了完整的 ICU 支持。

现在,依赖 ICU 的所有 JavaScript API 都应能与浏览器 API 匹配。

在 REPL 中尝试一下:

代码语言:javascript
复制
$ deno
Deno 1.8.0
exit using ctrl+d or close()
> const d = new Date(Date.UTC(2020, 5, 26, 7, 0, 0));
undefined
> d.toLocaleString("de-DE", {
weekday: "long",
year: "numeric",
month: "long",
day: "numeric",
});
"Freitag, 26. Juni 2020"

改进的覆盖率工具链:deno coverage

这个版本扩大了我们的覆盖率基础架构,添加了一些强大的新功能。此版本的主要变化是,覆盖率处理现在分为覆盖率集合和覆盖率报告。

以前,覆盖率的收集和报告都在单个子命令中进行,只需在启动 deno test 时指定 --coverage 标志即可。现在,用于 deno test 的 --coverage 标志接收一个参数——用来存储收集的配置文件的目录路径。这是覆盖率集合。在第二步中,你现在调用 deno coverage 以及存储覆盖率配置文件的目录路径。这条子命令可以直接在控制台上以漂亮的文本输出形式返回报告,也可以输出一个 lcov 文件(–lcov 标志)以供 genhtml、coveralls.io 或 codecov.io 之类的工具使用。

一段时间以来,我们一直在 deno_std 上测试这个功能。对于每次提交,我们都上传一份覆盖率报告到 codecov.io。你可以在这里 https://codecov.io/gh/denoland/deno_std 查看这些内容。需要添加的内容很少,我们的 GitHub Actions 工作流仅做了 10 行更改:

有关与 coveralls.io 集成的示例,请参见以下存储库:https://github.com/lucacasonato/deno_s3

导入映射现在已稳定

导入映射在 Chrome 89 中已稳定,随后我们的实现也进行了更新以匹配该规范的最新版本,并且现在也被认为是稳定的。这意味着使用 --import-map 时不再需要 --unstable 标志。

代码语言:javascript
复制
$ deno run --import-map=./import_map.json ./mod.ts

此外,–import-map 标志现在不仅接受本地路径,而且接受 URL,从而使你可以从远程服务器加载导入映射。

代码语言:javascript
复制
$ deno run --import-map=https://example.com/import_map.json ./mod.ts

导入映射允许用户使用所谓的“裸(bare)”说明符来表示依赖关系,而不是相对或绝对文件地址 /http URL:

代码语言:javascript
复制
// Deno does not support such specifiers by default,
// but by providing an import map, users can remap bare specifiers
// to some other URLs.
import * as http from "std/http";

代码语言:javascript
复制
{
"imports": {
"std/http": "https://deno.land/std@0.85.0/http/mod.ts"
}
}

用户应记住,导入映射不可组合:这意味着你只能为 deno run/deno test 提供单个导入映射。正因如此,库作者仍应使用常规的、非裸的说明符(相对或绝对文件地址 /http URL);否则,库用户将需要手动将你库(和你的库依赖项)的裸说明符添加到其导入映射中。

导入映射的一个更有用的特性是能够将常规说明符重新映射为完全不同的说明符。例如,如果你的模块图中深深嵌套了一些破碎的依赖关系,则可以在将其固定到上游之前替换为固定版本;或者如果你使用了一个将哈希添加到模块文件名的构建过程,则可以引用该文件而无需在源代码中哈希,并仅在运行时使用导入映射重新映射说明符。

了解更多示例和详细说明,请参考规范:

https://github.com/WICG/import-maps#the-import-map

使用身份验证令牌获取模块

并非所有代码都可以在公共互联网上公开获取。以前,Deno 无法从需要身份验证的服务器上下载代码。在这个版本中,我们增加了在第一次获取模块时由用户指定每个域的身份验证令牌的功能。

为此,Deno CLI 将查找名为 DENO_AUTH_TOKENS 的环境变量,以确定在请求远程模块时应考虑使用的身份验证令牌。环境变量的值采用以分号(;)分隔的 n 个令牌的格式,其中每个令牌的格式为{token}@{hostname[:port]}。

例如,单个令牌看起来像这样:

代码语言:javascript
复制
DENO_AUTH_TOKENS=a1b2c3d4e5f6@deno.land

多个令牌看起来像这样:

代码语言:javascript
复制
DENO_AUTH_TOKENS=a1b2c3d4e5f6@deno.land;f1e2d3c4b5a6@example.com:8080

当 Deno 要获取一个远程模块,其主机名与远程模块的主机名匹配时,Deno 会将请求的 Authorization 标头设置为 Bearer {token}的值。这会让远程服务器识别出该请求是一个要绑定到特定的,经过身份验证的用户的授权请求,并提供对服务器上适当资源和模块的访问权限。更详细的使用指南,以及配置环境以从私有 GitHub 存储库中获取信息的说明,请参见相关的手册条目:

https://deno.land/manual/linking_to_external_code/private

Deno.test 的 Exit 清理器

Deno.test API 已经有了两个清理器,它们可以帮助确保你的代码不会“泄漏”操作或资源——也就是说在测试用例结束之前,所有打开的文件 / 网络句柄都已关闭,并且没有其他挂起的系统调用。

Deno 1.8 添加了一个新的清理器,以确保经过测试的代码不会调用 Deno.exit()。异常 exit 语句可能会提供假正测试结果,并且经常被滥用或忘记删除。

默认情况下,所有测试都会启用这个清理器,但可以在测试定义中将 sanitizeExit 布尔值设置为 false 来禁用它。

代码语言:javascript
复制
Deno.test({
name: "false success",
fn() {
Deno.exit(0);
},
sanitizeExit: false,
});
// This test is never run
Deno.test({
name: "failing test",
fn() {
throw new Error("this test fails");
},
});

你可以自己运行这个脚本:

deno testhttps://deno.land/posts/v1.8/exit_sanitizer.ts

Deno.permissions API 现在已稳定

Deno 的安全模型基于众多权限。当前,只有在启动应用程序时才能授予这些权限。这在大多数情况下都没问题,但在某些情况下,在运行时请求 / 撤消权限会带来更好的用户体验。

在 Deno 1.8 中,现在有一个稳定的 API 可以 query、request 和 revoke 各种权限。这些 API 包含在 Deno.permissions 对象中。下面是它的工作机制的一个示例:

代码语言:javascript
复制
function homedir() {
try {
console.log(`Your home dir is: ${Deno.env.get("HOME")}`);
} catch (err) {
console.log(`Failed to get the home directory: ${err}`);
}
}
// Try to get the home directory (this should fail, as no env permission yet).
homedir();
const { granted } = await Deno.permissions.request({ name: "env" });
if (granted) {
console.log(`You have granted the "env" permission.`);
} else {
console.log(`You have not granted the "env" permission.`);
}
// Try to get the home directory (this should succeed if the user granted
// permissions above).
homedir();
await Deno.permissions.revoke({ name: "env" });
// Try to get the home directory (this should fail, as the permission was
// revoked).
homedir();

你可以自己运行这个脚本:

deno runhttps://deno.land/posts/v1.8/permission_api.ts

Deno.link 和 Deno.symlink API 已稳定

这个版本带来了与 symlink 相关的四个稳定的 API:

  • Deno.link
  • Deno.linkSync
  • Deno.symlink
  • Deno.symlinkSync

在这些 API 稳定之前,需要对它们进行安全检查,并且需要适当的权限才能使用它们。

Deno.link 和 Deno.linkSync 要求对源路径和目标路径都具有读写权限。

Deno.symlink 和 Deno.symlinkSync 要求对目标路径具有写权限。

更细粒度的 Deno.metrics

随着 Deno 变得更加稳定,对于开发人员来说,使用简单的方法来检测应用程序的需求就变得越来越重要。这里的工作从最低级别(运行时本身)开始。在 Deno 中,JS 的所有特权操作(转到 Rust 的那些操作)都是通过 JS 和 Rust 之间的单个中央接口来完成的。我们称通过该接口的请求为“ops”。例如,调用 Deno.open 将调用特权端的 op_open_asyncop,这将返回打开文件的资源 ID(或错误)。

两年多以前,即 2018 年 10 月 11 日,我们为你提供了一种查看 Rust 和 JS 之间所有操作指标的方法:Deno.metrics。这一 API 当前可以公开开始和完成的同步和异步操作的数量,以及通过 ops 接口发送的数据量。之前,这仅限于所有不同 ops 的组合数据。无法确定哪个 ops 被调用了多少次,只有一个总体结果。

运行时如果启用 --unstable,这个版本会向 Deno.metrics 添加一个名为 ops 的新字段。此字段包含每个 ops 的信息,这些信息涉及 API 的调用频率以及通过 API 传输的数据量。这样你就能对运行时进行更精细的检测。

下面是示例:

代码语言:javascript
复制
$ deno --unstable
Deno 1.8.0
exit using ctrl+d or close()
> Deno.metrics().ops["op_open_async"]
undefined
> await Deno.open("./README.md")
File {}
> Deno.metrics().ops["op_open_async"]
{
opsDispatched: 1,
opsDispatchedSync: 0,
opsDispatchedAsync: 1,
opsDispatchedAsyncUnref: 0,
opsCompleted: 1,
opsCompletedSync: 0,
opsCompletedAsync: 1,
opsCompletedAsyncUnref: 0,
bytesSentControl: 54,
bytesSentData: 0,
bytesReceived: 22
}

在即将发布的版本中,Deno.test 中的异步 ops 清理器将使用这份新信息,以在测试完成之前未完成异步 ops 时提供更多可行错误。我们已经看到该功能被用于检测应用程序,并将数据通过管道传输到监视软件中:

JSON 对 deno FMT 的支持

deno fmt 现在可以格式化.json 和.jsonc 文件。就像 JS/TS 一样,格式化程序还将在 markdown 文件中格式化 json 和 jsonc 代码块。

IIFE 软件包对 Deno.emit 的支持

内置打包器现在可以发出立即调用函数表达式(IIFE)格式的包。

默认情况下,输出格式仍为 esm,但用户可以将 EmitOptions.bundle 选项设置为 iife 来更改此格式:

代码语言:javascript
复制
const { files } = await Deno.emit("/a.ts", {
bundle: "iife",
sources: {
"/a.ts": `import { b } from "./b.ts";
console.log(b);`,
"/b.ts": `export const b = "b";`,
},
});
console.log(files["deno:///bundle.js"]);

结果是:

代码语言:javascript
复制
(function() {
const b = "b";
console.log(b);
return {
};
})();

你可以自己运行此脚本:

deno run --unstablehttps://deno.land/posts/v1.8/emit_iife.ts

为不支持 ESM 的较旧浏览器创建打包时,这个特性特别有用。

deno lsp 现在已稳定

在过去的几个月中,我们一直在努力替换旧的 VS Code 编辑器集成(Deno 扩展)。旧的扩展仅适用于 VS Code,而且解析的类型并不总是与 Deno CLI 中的类型匹配。

在 Deno 1.6 中,我们在 canary(Deno 的内置语言服务器)中发布了 deno lsp。LSP 使我们能够从单个代码库向所有支持 LSP 的编辑器提供编辑器集成。内置的语言服务器与 Deno CLI 的其余部分基于相同的架构——因此,它提供的 TypeScript 诊断与 CLI 的其余部分相同。

两周前,在 Deno 1.7.5 中,我们稳定了 deno lsp 并将正式的 VS Code 扩展切换到它上。到目前为止,我们已经收到了很好的反馈,并将努力解决所有报告的问题。如果你在扩展中遇到问题,请在我们的问题跟踪器中报告。我们无法解决我们不知道的问题。

除了官方的 VS Code 集成之外,大家还创建了更多基于 deno lsp 构建的社区集成:

原文链接:

https://deno.land/posts/v1.8

  • 发表于:
  • 本文为 InfoQ 中文站特供稿件
  • 首发地址https://www.infoq.cn/article/zsRyZ9mXL3ljEEV50HNf
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券