Deno 1.39:WebGPU 的回归

Deno 1.39 标志着 Deno 生态系统的重大更新,具有 回归 万众期待的WebGPU , 增强图形、游戏和机器学习的能力。 我们还曾 引入了新的 deno 覆盖报告器以改进代码库分析,并制作 Node.js 兼容性方面取得了重大进展,简化了 Node.js 的过渡 开发商。 最后,此版本包括对标准库的更新, 性能优化以及最新的 TypeScript 5.3 支持。


如果您已经安装了 Deno,请在终端中升级到版本 1.39 和:

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.39 新增功能的概述:

WebGPU 回来了

WebGPU API 为开发人员提供了一种低级别、高性能、跨架构的方式 从 JavaScript 编程 GPU 硬件。 它是 WebGL 的有效继承者 网络。 该规范已经最终确定,Chrome 也已经发布了 API。 Firefox 和 Safari 正在提供支持。

德诺 早在 2021 年初首次引入 WebGPU 但由于性能问题,它在今年早些时候被删除。 有了这个 发布后,我们很高兴重新推出它并解决所有性能问题 出去。

GPU 能够以极端的方式计算某些数值运算 与 CPU 相比的并行性。 这对于各种应用都很有用, 不仅仅是渲染和游戏。 例如,机器学习算法可以 通常表示为一系列矩阵运算,可以计算 在 GPU 上极其高效。

我们的 WebGPU 实现基于与即将推出的相同的底层系统 Firefox 中的 WebGPU 实现,因此我们相信它是可靠的 为开发人员构建基础。

通过 WebGPU 获取有关 GPU 信息的基本示例:

// 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.
  const adapterInfo = await adapter.requestAdapterInfo();
  console.log(`Found adapter: ${adapterInfo.device}`); // On some systems this will be blank
  const features = [...adapter.features.values()];
  console.log(`Supported features: ${features.join(", ")}`);
} else {
  console.error("No adapter found");
}

更多示例可以在我们的网站上查看 webgpu-examples 存储库

尽管规范稳定,但 WebGPU 在以下方面仍被认为不稳定 德诺。 要在 Deno 中访问它,请使用 --unstable-webgpu旗帜。 我们计划 在我们有机会从 社区和更多的时间来验证实施情况 规范测试套件

对于更多 webgpu 功能,我们还添加了 std/webgpu (更多信息如下)。

感谢 wgpu 团队提供的帮助 为了达成这个。

新的 deno coverage记者

在此版本中, deno coverage接待了两位新记者: summary和 html。 您现在还可以省略目录值 --coverage标记在 deno test,因为我们现在默认使用 ./coverage/目录。

这 summary报告者是新的默认报告者。 它输出覆盖范围 简洁表格中的摘要,为您提供有关覆盖范围的特别信息 文件和总体摘要:

$ deno coverage
----------------------------------
File         | Branch % | Line % |
----------------------------------
 bar.ts      |      0.0 |   57.1 |
 baz/quux.ts |      0.0 |   28.6 |
 baz/qux.ts  |    100.0 |  100.0 |
 foo.ts      |     50.0 |   76.9 |
----------------------------------
 All files   |     40.0 |   61.0 |
----------------------------------

以前默认的报告器将所有文件中未覆盖的行打印到 终端仍然可以使用 --detailed旗帜。

您还可以指定 --html标记以获取 HTML 格式的详细覆盖率报告 格式。

$ deno test --coverage
$ deno coverage --html
HTML coverage report has been generated at file:///path/to/project/coverage/html/index.html

覆盖率报告的示例如下所示:

的输出 deno coverage --html是完全静态的,可以托管在 任何静态文件服务器,例如 GitHub Pages。

我们依然支持 --lcov标志,输出覆盖率报告 LCOV 格式,适用于 与其他工具集成,例如 Codecov 工作服

我们有进一步的计划来改进 deno coverage并使其更有用。 如果你 有您想要分享的反馈,请评论 这个问题

更新至 deno compile

Deno 1.39 在以下方面引入了重大进步 deno compile特征:

更好的 node_modules支持 :随着 --unstable-byonm旗帜, deno compile现在支持“自带node_modules”,增强Node.js 兼容性。 此功能允许您直接在 Deno 中使用 npm 包 项目,弥合了 Deno 和广泛的 npm 生态系统之间的差距。 学习 有关此功能的更多信息,请参见 我们之前的博客文章

可执行文件的灵活命名 :Deno 删除了对可执行文件的限制 命名。 您现在可以使用前导数字来命名编译的程序,例如 3d_modeler,在命名约定方面提供更大的灵活性。

更多动态导入支持 :现在支持更多动态导入模式 在 deno compile。 这很有趣,因为 Deno 需要静态包含 可以在运行时在生成的二进制文件中导入的所有模块 deno compile。 因此,动态导入可能会出现问题。 现在,德诺 可以处理更多动态导入模式,例如:

await import(`./dir/${expr}`);


在此示例中,Deno 将包含来自 ./dir/和它的 子目录到编译的二进制文件中。 这允许您导入其中任何一个 运行时的文件。 此更新通过确保以下内容简化了依赖关系管理 动态引用的所有模块在运行时都可用。

增强型语言服务器

在我们持续致力于改进 Deno 语言服务器 (LSP) 的过程中,这 版本引入了显着的性能增强。

响应式打字体验 :我们优化了快速请求的处理 快速打字时爆发,确保更流畅、更灵敏的编辑 IDE 中的经验。

关闭超时 :为了解决“僵尸”LSP 实例挥之不去的问题, 我们已经实现了关闭超时机制。 这个功能强行 当您在设置的超时后关闭编辑器时终止 LSP 进程, 促进资源高效利用。

更新通知 :语言服务器现在主动通知您 最新的 Deno 更新。 此功能旨在简化保留您的信息的过程 Deno 安装最新版本,确保您始终能够访问最新版本 功能和修复。

增强诊断 :我们引入了新的 deno.logFile设置在 VS 代码。 并用时 deno.internalDebug,此功能允许 捕获详细的诊断数据,有助于性能分析和 故障排除。

我们致力于不断增强 Deno LSP。 如果你遇到 LSP 或 VSCode Deno 中的任何性能问题,您的反馈是 无价。 请告诉我们您的经历 这里

Node.js 兼容性改进

草率的进口

将现有 TypeScript 代码库迁移到 Deno 可能是一项艰巨的任务。 之一 最大的障碍是 Deno 要求你显式指定 导入语句中的文件扩展名。

想象一个包含文件的 TypeScript 项目 foo.ts进口的 bar.ts:

// foo.ts
import { Example } from "./bar";
console.log(Example);
// bar.ts
export const Example = "Example";

在 Deno 的早期版本中,这会出错并显示无用的消息:

# Deno v1.38.5
$ deno run foo.ts
error: Module not found "file:///dev/bar"
  at file:///dev/foo.ts:1:25

现在,在 Deno 1.39 中,此错误消息得到了改进,并制作了逃生舱口 可用的:

# Deno v1.39.0
$ deno run foo.ts
error: Module not found "file:///dev/bar". Maybe add a '.ts' extension or run with --unstable-sloppy-imports
    at file:///dev/foo.ts:1:25

运行与 --unstable-sloppy-importsflag 将执行代码而无需 任何变化:

# Deno v1.39.0
$ deno run --unstable-sloppy-imports foo.ts
Warning Sloppy imports are not recommended and have a negative impact on performance.
Warning Sloppy module resolution (hint: add .ts extension)
    at file:///dev/foo.ts:1:25
Example

除了解决没有文件扩展名的导入问题之外,此功能还 允许解决“目录”导入以及导入 .ts 文件使用 .js扩大:

// routes/index.ts
export default {
  "/": () => "Hello World",
  "/example": () => "Example",
};
// bar.ts
export const bar = "bar";
// foo.ts
import routes from "./routes";
import { bar } from "./bar.js";
console.log(routes);
console.log(bar);
$ deno run --unstable-sloppy-imports foo.ts
Warning Sloppy imports are not recommended and have a negative impact on performance.
Warning Sloppy module resolution (hint: specify path to index.ts file in directory instead)
    at file:///Users/ib/dev/deno/foo.ts:1:20
Warning Sloppy module resolution (hint: update .js extension to .ts)
    at file:///Users/ib/dev/deno/foo.ts:2:21
{ "/": [Function: /], "/example": [Function: /example] }
bar

如上所示,使用此标志将打印警告,引导您 将代码迁移到推荐的导入语法。 您还将得到 编辑器中的诊断以及“快速修复”将使您更容易 应用必要的更改。

我们希望此功能将使尝试和迁移现有的变得更加容易 项目到 Deno。

支持跑步 node_modules/.bin/可执行文件在 deno task

deno task可以运行中定义的任务 deno.json, 也 scripts定义的 在 package.json。 此版本添加了对运行可执行文件的支持 node_modules/.bin/目录在 deno task。

如果你有 package.json看起来像这样:

{
  "scripts": {
    "dev": "vite dev"
  }
}

你可以运行 vite dev 和 deno task:

$ deno task dev

德诺将寻找 vite 可执行于 node_modules/.bin/ 目录并运行 它使用 Deno - 即使 node_modules/.bin/vite使用 shebang 定义 Node.js 作为解释器。

CommonJS 入口点位于 node_modules

Deno 现在可以正确处理 CommonJS 入口点 node_modules, 尊重 type设置从 package.json以获得相关的包。 这 应该大大提高与尚未迁移的软件包的兼容性 到 ESM。

支持 Object.prototype.__proto__

Deno 有意识地决定不支持 Object.prototype.__proto__为了 安全原因。 不过还是有很多包 npm依赖于 该属性才能正常工作。

在此版本中,我们引入了一个新的 --unstable-unsafe-proto允许的标志 您启用此属性。 不建议使用此标志,但如果您 确实需要使用依赖它的包,逃生舱口现在是 可供您使用。

Node.js API 更新

以下 Node.js API 现已可用:

  • crypto.createPrivateKey
  • http.ClientRequest.setTimeout
  • http.globalAgent
  • perf_hooks.performance
  • process.geteuid
  • process.report
  • util.parseArgs
  • vm.runInNewContext

此外,我们还修复了已支持的 Node.js API 中的几个错误:

  • child_process.spawnSync处理 status不正确
  • child_process.spawnSync适当地正常化 stdio
  • child_process可以处理 Unix 系统上的 IPC 管道(Windows 支持即将到来 很快)
  • crypto.sign现在可以使用 PEM 私钥
  • fs.existsSync当文件不存在时现在速度更快
  • process.exitCode应该更改进程的退出代码
  • 允许 null价值 http.OutgoingMessage.setHeader
  • 使固定 Buffer.copy什么时候 sourceStart> source.length
  • 使固定 os.freemem
  • 使固定 stream.Writable
  • 手柄关闭 process.stdin不止一次

更改为 Deno蜜蜂

此版本包括对 Deno蜜蜂:

Deno.serve()对 Unix 套接字的支持现已稳定

Deno.serve(
  { transport: "unix", address: "/tmp/my.sock" },
  (req) => new Response("Hello!"),
);

Deno.HttpServer.shutdown()现在已经稳定了

const server = Deno.serve((req) => new Response("Hello!"));<
>>
// Shutdown the server gracefully when the process is interrupted.
Deno.addSignalListener("SIGINT", () => {
  server.shutdown();
});
await server.finished;

Deno.HttpClient现在可以声明为 using关键词

跟进 Explicit Resource Management 介绍给 Deno蜜蜂 在上一个版本中 ,此版本带来了 支持 using关键字到 Deno.HttpClient:

{
  using client = Deno.createHttpClient({});
  const response = await fetch("http://localhost:4545/assets/fixture.json", {
    client,
  });
  const json = await response.json();
}
// `client` is closed here

KV手表

新的,不稳定的 Deno.Kv.watch()用于监视给定键的更改的 API 在给定的数据库中。 该 API 返回一个 ReadableStream发出新的 每当任何监视的键更改其版本标记时,都会值。 发射的 值是一个数组 Deno.KvEntryMaybe对象,具有相同的长度和顺序 这 keys大批。 请在此处阅读有关 KV 手表功能的更多信息。

const db = await Deno.openKv();<
>>
const stream = db.watch([["foo"], ["bar"]]);
for await (const entries of stream) {
  entries[0].key; // ["foo"]
  entries[0].value; // "bar"
  entries[0].versionstamp; // "00000000000000010000"
  entries[1].key; // ["bar"]
  entries[1].value; // null
  entries[1].versionstamp; // null
}

克朗

这 Deno.cron最近推出的功能有了令人兴奋的更新 这个版本。 它现在支持直观的 JSON 格式来定义时间表, 使 cron 作业更容易理解和实施。 为了更深入 信息, 浏览我们关于 cron 功能的详细博客文章

传统 Unix Cron 格式

以前,设置任务每 20 分钟运行一次需要 Unix cron 格式:

Deno.cron("myCron", "*/20 * * * *", () => {
  console.log("Running every 20 minutes");
});

新的 JSON 格式

现在,您可以使用更具可读性的 JSON 格式来实现相同的目的:

Deno.cron("myCron", {
  minutes: { every: 20 },
}, () => {
  console.log("Running every 20 minutes");
});

已弃用的 IO 接口

我们一直在推动 Deno要使用的 API 网络流 API 几个月来,为了完成这一更改,v1.39 版本带来了 弃用 Deno 中的各种 IO 接口。

以下接口现已弃用,并将在 Deno 中删除 2:

  • Deno.Reader
  • Deno.ReaderSync
  • Deno.Writer
  • Deno.WriterSync
  • Deno.Closer

现在,在使用这些界面时,您将在编辑器中收到警告 建议改用 Web Streams API。

Web API 的更改

AbortSignal.any()

该 API 允许监听多个 AbortSignals, 如果任何指定信号被中止,则将中止。

如果您有一个提供以下功能的 API,这会很有用 AbortSignal(为了 例子, Request), 并且您还想依赖另一个 AbortSignal。

ImageData

这 ImageDataWeb API 是一个可用于表示图像的类 标准化格式。

创建 1x2 像素红色图像的简单示例:

const rawImage = new Uint8ClampedArray([255, 0, 0, 1, 255, 0, 0, 1]);
new ImageData(rawImage, 1, 2);

谢谢 @jamsinclair谁贡献了这个 特征。

ReadableStream.read min选项

这 min选项 ReadableStreamBYOBReader.read允许指定 要读取的最小字节数。 这对于各种编码格式很有用 需要读取 n 个字节,这可以通过设置 min选项的长度与缓冲区的字节长度相同。

例如:

const response = await fetch("https://example.com");
const reader = response.body!.getReader({ mode: "byob" });
const buffer = new Uint8Array(10);
// value will contain at least 5 bytes written to it
const { value } = await reader.read(buffer, { min: 5 });

改进 URLPattern表现

这 URLPatternAPI 的性能得到了改进,从 6 提升到 8 匹配多个模式时速度要快几倍,这是一种优化 针对流行的使用场景 URLPattern在 HTTP 路由器中。

标准库更新

std/webgpu

除了在 CLI 中发布 WebGPU 之外,我们还添加了 std/webgpu在这个 发布。

该模块添加了一些附加功能,包括 createTextureWithData 用于创建一个 GPUTexture与现有数据, describeTextureFormat 获取有关纹理格式的信息,以及 createCapture 使用纹理等进行“捕捉”。

其中一些功能已被移植/基于 wgpu特性和更多功能 已计划。

std/expect

在此版本中 std/expect已添加。 这 模块导出两个函数: expectfn。 这些设计目的是 与笑话兼容。

import { expect } from "https://deno.land/std@0.209.0/expect/mod.ts";<
>>
expect(Math.max(5, 8)).not.toEqual(5);
expect(Math.max(5, 8)).toEqual(8);
expect(Math.pow(3, 5)).toBeGreaterThan(100);
expect(Math.pow(3, 5)).toBeLessThan(300);

现在 expect 支持以下匹配器和修饰符 API: not , resolves , rejects , toBe , toEqual , toStrictEqual , toMatch , toMatchObject , toBeDefined , toBeUndefined , toBeNull , toBeNaN , toBeTruthy , toBeFalsy , toContain , toContainEqual , toHaveLength , toBeGreaterThan , toBeGreaterThanOrEqual , toBeLessThan , toBeLessThanOrEqual , toBeCloseTo , toBeInstanceOf , toThrow , toHaveProperty , toHaveLength。

该模块还提供了mock相关的util和断言:

import { expect, fn } from "https://deno.land/std@0.209.0/expect/mod.ts";<
>>
const mockFn = fn();
mockFn();
mockFn();
mockFn();
expect(mockFn).toHaveBeenCalled();
expect(mockFn).not.toHaveBeenCalledTimes(1);
expect(mockFn).toHaveBeenCalledTimes(3);

实现了以下模拟相关匹配器: toHaveBeenCalled , toHaveBeenCalledTimes , toHaveBeenCalledWith , toHaveBeenLastCalledWith , toHaveBeenNthCalledWith , toHaveReturned , toHaveReturnedTimes , toHaveReturnedWith , toHaveLastReturnedWith , toHaveNthReturnedWith。

该模块不完全兼容 expect笑话的 API。 下列 API 尚未 实现: toMatchSnapShot, toMatchInlineSnapShot, toThrowErrorMatchingSnapShot, toThrowErrorMatchingInlineSnapShot, expect.anything, expect.any, expect.arrayContaining, expect.not.arrayContaining, expect.closedTo, expect.objectContaining, expect.not.objectContaining, expect.stringContaining, expect.not.stringContaining, expect.stringMatching, expect.not.stringMatching, expect.assertions, expect.hasAssertions, expect.addEqualityTester, expect.addSnapshotSerializer, expect.extend。

标准库还有 std/testing/bdd模块。 现在你可以 使用标准库以 BDD 风格编写测试用例。

import { describe, it } from "https://deno.land/std@0.209.0/testing/bdd.ts";
import { expect } from "https://deno.land/std@0.209.0/expect/mod.ts";
describe("Math", () => {
  describe("max", () => {
    it("returns max value from the given args", () => {
      expect(Math.max(1, 2, 3)).toEqual(3);
      expect(Math.max(-3, -2, -1)).toEqual(-1);
    });
  });
});

将此文件另存为 my_test.ts你可以使用以下命令执行它:

$ deno test my_test.ts
Check file:///path/to/my_test.ts
running 1 test from ./my_test.ts
Math ...
  max ...
    returns max value from the given args ... ok (1ms)
  max ... ok (1ms)
Math ... ok (1ms)
ok | 1 passed (2 steps) | 0 failed (1ms)

感谢 Thomas Cruveilher 做出的贡献 此功能。

std/ini

在此版本中 std/ini已添加。 这 模块提供解析器和序列化器以供使用 INI 文件

感谢亚伦 ·哈金斯 为此做出的贡献 特征。

std/data_structures

std/data_structures已添加到 这个版本。 该模块导出实现的类 数据结构 算法。 现在 RedBlackTree, BinarySearchTree, 和 BinaryHeap类是 可用的。

std/text

std/text已在此版本中添加。 这 模块导出用于比较/排序/选择文本的实用函数 某些标准:

import {
  closestString,
  levenshteinDistance,
} from "https://deno.land/std@0.209.0/text/mod.ts";
// Calculates levenshtein distance of 2 words
console.log(levenshteinDistance("hello", "halo")); // => prints 2
console.log(levenshteinDistance("hello", "world")); // => prints 4
console.log(closestString("puhs", ["commit", "pull", "push"])); // => prints "push"

感谢 Jeff Hykin 贡献这些 特征。

std/cli

std/cli已在此版本中添加。 这 模块当前导出 2 个 API: parseArgs和 promptSecret。

import {
  parseArgs,
  promptSecret,
} from "https://deno.land/std@0.209.0/cli/mod.ts";
const parsedArgs = parseArgs(["--foo", "--bar=baz", "./quux.txt"]);
console.log(parsedArgs);
// prints: { foo: true, bar: "baz", _: ["./quux.txt"] }
// This is typically used as `parseArgs(Deno.args)`
const credential = promptSecret("Enter the credential ");
// This asks for the credential in the terminal and the user inputs are masked with '*'

笔记: parseArgs 是相同的 parse 在 std/flags ,但我们意识到 范围 std/flags 太有限了,决定探索更多CLI相关的 下的功能 std/cli。

感谢 Alisue 的提议和实施 promptSecret。

std/net

std/net已在此版本中添加。 这 模块导出1个API: getAvailablePort,这对于选择可用的 TCP 端口。

import { getAvailablePort } from "https://deno.land/std@0.209.0/net/mod.ts";<
>>
const port = await getAvailablePort();

感谢 Harry Solovay 对此做出的贡献 特征。

打字稿 5.3

Deno v1.39 附带最新版本的 TypeScript 5.3,请阅读更多内容 宣布 TypeScript 5.3 博客文章。

装饰器即将发生的变化

目前,Deno 支持 实验性 TypeScript 装饰器 默认情况下。 由于 TC39 装饰器提案 是 在第 3 阶段和 一个受欢迎的请求 我们决定的 在即将发布的 Deno v1.40 版本中更改装饰器的默认设置。

在下一个版本中,实验性的 TypeScript 装饰器将被禁用 默认情况下,TC39 装饰器将默认启用。

如果您正在使用实验性 TS 装饰器,请通过以下方式为这一更改做好准备: 将此配置添加到您的 deno.json:

{
  "compilerOptions": {
    "experimentalDecorators": true
  }
}

感谢我们的贡献者!

如果没有社区的帮助,我们就无法构建 Deno! 是否通过回答 在我们的社区 Discord 服务器 中提出问题或 报告错误 ,我们非常棒 感谢您的支持。 我们特别要感谢以下人员 人们对 Deno 1.39 的贡献:Aravind、Birk Skyum、Bolat Azamat、 陈苏、丹尼尔·米泽斯基、弗洛里安·施瓦尔姆、加斯曼、伊恩·布尔、雅各布·哈默、雅库布 吉鲁特卡、杰米、杰西·杰克逊、约翰·斯珀洛克、乔丹·哈班德、朱利安·凯扎克、 杰罗姆·伯努瓦、森内健太、劳伦斯·罗、马克斯·古德哈特、拉希德·安瓦尔、 Tareque Md Hanif、btoo、citrusmunch、lionel-rowe、liruifengv、pk、围巾、ud2、 和林炳权。

您想加入 Deno 贡献者的行列吗? 在这里查看我们的贡献文档 , 我们下次会在名单上见到你。

不管你相信与否,上面列出的变化仍然没有告诉你所有的事情 1.39 有所好转。 您可以查看 Deno 中合并的拉取请求的完整列表 1.39 在 GitHub 上

感谢您关注我们的 1.39 版本,我们希望您喜欢构建 与德诺! 

© GVGNN 2013-2026