跳至主要内容
Deno 2 终于来了 🎉️
了解更多
Deno 1.42

Deno 1.42:JSR 带来更强大的依赖管理

我们对 Deno 的愿景是简化编程,而依赖管理是其中一个重要的方面。虽然 npm 已经发展成为最成功的开源注册中心,但在那里使用和发布模块变得越来越复杂

基于 npm 的成功,JSR 提供了一个现代、以 TypeScript 为首的跨平台兼容注册中心,完全集成到 Deno 中。

Deno v1.42 通过 deno publishdeno add 子命令 提供了更强大的依赖管理,可以从 JSR 和 npm 发布和安装模块。此外,此版本还提供 改进的 Node/npm 兼容性多个 LSP 改进更快的启动时间(以及其他性能优势)等等。

如果您已安装 Deno,请在您的终端中将其升级到 1.42 版

deno upgrade

如果您尚未安装 Deno,您可以使用以下命令之一进行安装,或 通过其他多种方式 进行安装。

MacOS/Linux 安装

curl -fsSL https://deno.land/install.sh | sh

Windows 安装

irm https://deno.land/install.ps1 | iex

以下是 Deno 1.42 中新功能的概述

JSR、deno publishdeno add

JSR 是一个新的开源注册中心,用于现代 JavaScript 和 TypeScript 包。 了解我们构建 JSR 的原因。. JSR 使用起来非常愉快。它消除了分发 TypeScript 和 JavaScript 的所有麻烦。我们相信您会喜欢它。

在 1.42 中,对 JSR 的一流支持已添加到 Deno 中。这意味着无需任何额外工具,您就可以使用和发布模块到 JSR。

有两个新的子命令。第一个是 deno add。它与 npm add 的工作方式相同,但默认使用 JSR 包。例如,如果您想使用来自 JSR 的 @std/assert,您只需运行

deno add @std/assert

这将添加一个导入映射条目,允许您在代码中轻松导入

import { assertEquals } from "@std/assert";
assertEquals(1, 2);

请注意,deno add 也支持使用 npm: 前缀添加 npm 包。

对于模块作者,deno publish 可以按照您的预期进行,它会发布到 JSR。点击此处了解所有信息。

JSR 也完全烘焙到 Deno 的 LSP 和 VS Code 扩展中。即使使用 TypeScript,跳转到定义也应该正常工作。智能感知应该可以完美地处理 JSR 包。

我们希望 听到您对这些新功能的反馈

Node.js 和 npm 兼容性

此版本中进行了很多改进,使 Deno 与 Node.js 更兼容

  • async_hooks 模块现在支持 EventEmitterAsyncResource AsyncLocalStorage.enterWith() API #22994 #22740

  • child_process.spawn() 正确处理 stdio 配置中的 null #23048

  • crypto 模块正在稳步变得更加完整。在此版本中,我们添加了 getRandomValues()subtlegetCipherInfo()publicKey()createPublicKey() API,以及对多个 API 中更多曲线的支持。这些更改应该可以解除对 ssh2web-pushoctokit 等热门包的使用限制。 #22882 #22891 #23028

  • fs 收到了对 Windows “连接点”FsWatcher.ref()FsWatcher.unref()fs.statfs() API 的支持 #22987 #22294

  • http 模块现在导出 validateHeaderName()validateHeaderValue() API,并且 ServerResponse 现在正确支持设置 HTTP 方法 #22630 #22616

  • http2 收到了对 createServer() API 的基本支持 #22708

  • module.isBuiltin() 现在已支持 #22817

  • process.arch 现在支持 "riscv64"

  • process.argv0 现在已正确设置

  • process.version 已更新,以返回 v20.11.1,这是 Node.js 的最新 LTS 版本

  • process.setSourceMapsEnabled 现在可用,但只是一个空操作

  • punycode 模块工作正常 #22847

  • string_decoder.StringDecoder() 与 Node.js 的行为匹配 #22933

  • timers.setImmediate 与 Node.js API 和行为匹配 #22808

  • util.styleText 现在已支持 #22758

  • worker_threads 模块进行了重大改动。它现在正确支持 ES 模块和 CommonJS。以下 API 现在已支持:parentPortworkerDataisMainThreadthreadIdreceiveMessageOnPort()ref()unref()。工作线程现在同步设置,并在空闲时自动终止。 #22841 #20794 #22950 #22647 #22884 #22815 #22766 #22778

  • v8.serialize()v8.deserialize() 已实现 #22975 #22975

以及与 npm 兼容性相关的若干改进

  • 用户代码现在可以从 node_modules/ 目录正确导入 CommonJS 文件

  • 现在支持内部条件导出(以 # 开头的导出,例如 #crypto

  • 在类型检查期间,CSS 文件会从 npm 包中正确解析

此外,还对设置 node_modules/ 目录的性能进行了改进 - 您可以在 Deno v1.42 中看到高达 1.7 倍的提速。

deno task

跨平台 shebang 支持已在 deno task 中实现,适用于任何以 #!/usr/bin/env -S 开头的 shebang。

给定 script.ts 文件和 deno.json

#!/usr/bin/env -S deno run
console.log("Hello there!");
{
  "tasks": {
    "hi": "./script.ts"
  }
}

现在运行此任务可以正常工作,即使在 Windows 机器上也是如此

> pwd
C:\Users\david\dev\my_project
> deno task hi
Hello there!

退出状态变量

shell 现在支持使用 $? 获取最后运行命令的退出代码

{
  "tasks": {
    // outputs 10
    "output": "deno eval 'Deno.exit(10)' || echo $?"
  }
}

改进的重定向支持

现在已实现输入重定向和更多文件描述符重定向

{
  "tasks": {
    // redirect file.txt to the stdin of gzip
    "input-redirect": "gzip < file.txt",
    // redirect stdout to stderr
    "stdout-err": "deno run main.ts >&2",
    // redirect stderr to stdout
    "stderr-out": "deno run main.ts 2>&1"
  }
}

任务说明

如果您使用的是 JSONC 文件,现在可以使用注释为您的任务添加说明

{
  "tasks": {
    // Start development server
    "dev": "deno run --watch main.ts",

    /**
     * Run tests with coverage and output HTML report
     */
    "coverage": "deno test --coverage **/*_test.ts && deno coverage --html"
  }
}
$ deno task
- dev
  // Start development server
  deno run --watch main.ts

- coverage
  // Run tests with coverage and output HTML report
  deno test --coverage **/*_test.ts && deno coverage --html

deno lint --fix

现在可以在命令行和编辑器中通过快速修复功能自动修复 lint 规则。

例如,给定以下代码

window.onload = () => console.log("Hi there!");

deno lint 现在输出以下内容

> deno lint
error[no-window]: window is deprecated and scheduled for removal in Deno 2.0
 --> main.ts:1:1
  |
1 | window.onload = () => console.log("Hi there!");
  | ^^^^^^
  = hint: Instead, use `globalThis`

  docs: https://lint.deno.land/rules/no-window


Found 1 problem (1 fixable via --fix)
Checked 1 file

注意文本 (1 fixable via --fix)。让我们试试吧

> deno lint --fix
Checked 1 file
> cat main.ts
globalThis.onload = () => console.log("Hi there!");
> deno lint
Checked 1 file

目前,这仅适用于三个 lint 规则,但列表会随着时间的推移而增长。

--watch-exclude=...

有时在使用 --watch 标志时,您可能不希望某些文件触发重启。现在可以使用 --watch-exclude 标志来实现这一点

# exclude file1.ts and file2.ts from being watched
deno run --watch --watch-exclude=file1.ts,file2.ts main.ts

您也可以排除模式,但请记住将它放在引号中,以防止您的 shell 在将参数发送到 Deno 之前展开它们

# exclude any .js file from being watched
deno run --watch --watch-exclude='*.js' main.ts

jsr 标签和 verbatim-module-syntax lint 规则

包含 nameversionexports 字段的 deno.json 文件现在会自动选择 jsr lint 规则标签。

此标签包含以下规则

  • no-slow-types
  • verbatim-module-syntax (fixable via --fix)

no-slow-types lint 规则是 JSR 特定的,您可以在 jsr.io 上阅读有关它的内容。verbatim-module-syntax lint 规则强制 importexport 声明仅在它们仅用于类型位置时才将其标识符定义为类型。这对于确保在 jsr.io 上发布的代码在更多情况下有效非常重要。您可以在 TypeScript 5.0 版本说明 中阅读有关详细模块语法的更多信息。

类型检查不再在应用程序执行过程中进行

以前,如果您使用 --check 标志运行 deno run,Deno 可能会在遇到静态不可分析的动态导入或启动工作线程时在执行过程中进行类型检查。

此功能维护负担很大,在 JSR 中带来了一些挑战,并产生了在执行过程中可能导致正在运行的应用程序中途失败的不理想行为。出于这个原因,类型检查不再在初始类型检查之后进行(重点强调:deno run --check main.ts 仍然在执行任何模块 **之前** 进行类型检查)。

建议改用 deno check 子命令来根据需要对这些模块进行类型检查。

即将发布的 deno install 更改

deno install 允许您轻松安装和分发可执行代码。

$ deno install --allow-net --allow-read https://deno.land/std/http/file_server.ts
✅ Successfully installed file_server.
$ file_server
Listening on http://127.0.0.1:4507

我们已经收到反馈,虽然此命令很有用,但许多用户期望它将依赖项“安装”到项目的本地目录 - 就像之前介绍的 deno add 一样。

为了更好地符合预期,deno install 将在 Deno 2 中更改为将脚本安装到项目的本地目录。也就是说,deno install 将成为 deno add 的别名。

当前的行为仍然可以通过 -g / --global 标志来支持,以告诉 Deno 您要全局安装脚本。

$ deno install --global --allow-net --allow-read https://deno.land/std/http/file_server.ts
✅ Successfully installed file_server.

如果您省略了 -g / --global 标志,Deno 现在会向您发出警告并建议您使用它。

语言服务器改进

v1.37 起,我们的 LSP 一直支持 npm: 指定符的补全。在 v1.42 中,我们不仅添加了对 jsr: 指定符的支持,还添加了对包名称和版本的补全支持。

import "jsr:@std/a";
//     "jsr:@std/archive";
//     "jsr:@std/assert"; ✔️
//     "jsr:@std/async";
//     "jsr:@std/data-structures";
//     "jsr:@std/datetime";
//     ...
import "jsr:@std/assert@";
//     "jsr:@std/[email protected]"; ✔️
//     "jsr:@std/[email protected]";
//     "jsr:@std/[email protected]";
//     "jsr:@std/[email protected]";
//     "jsr:@std/[email protected]";
//     ...

其他改进和修复

  • 在 JSR 导入悬停文本中包含注册表 URL。
  • 不要警告有关来自 .js 到 .d.ts 文件的本地文件“重定向”。
  • 不要将符号重命名应用于供应商远程模块。
  • 对包指定符导入映射键应用尾部斜杠扩展。

性能

此版本在整个领域都看到了许多性能改进,其中最值得注意的是

更快的启动时间: Linux 上的启动时间提高了 10%。引导初始化现在在快照时间被预热,并减少了内存分配。

更有效的 setTimeoutsetInterval计时器已经过重大重写。创建一百万个计时器大约需要 1.4 秒,而 Deno 1.41 中需要 5.9 秒,同时内存使用量也降低了高达 70%。我们仍然有一些优化要做,我们将在未来几个月内继续努力。

V8 12.3 和 TypeScript 5.4.3

Deno 1.42 附带 V8 12.3 和 TypeScript 5.4.3。值得注意的变化包括 Set 方法的支持对迭代器助手(Iterator Helpers)的支持

以下是现在可用的功能

DENO_FUTURE=1 环境变量

Deno v1.42 添加了一个新的环境变量 DENO_FUTURE=1,它启用了将在期待已久的、多次延迟的 Deno 2 中发生的更改。

目前 DENO_FUTURE=1 启用了以下更改

  • 删除 window 全局变量
  • 删除以下 Deno API:Deno.BufferDeno.closeDeno.copyDeno.FileDeno.FsFile.prototype.ridDeno.fstatDeno.fstatSyncDeno.ftruncateDeno.ftruncateSyncDeno.flockDeno.flockSyncDeno.funlockDeno.funlockSyncDeno.iterDeno.iterSyncDeno.metricsDeno.readAllDeno.readAllSyncDeno.readDeno.readSyncDeno.resourcesDeno.seekDeno.seekSyncDeno.shutdownDeno.writeAllDeno.writeAllSyncDeno.writeDeno.writeSync

在接下来的版本中,我们将添加更多将在 Deno 2 中发生的更改,包括对处理 node_modules/ 目录的更改。特别是在 DENO_FUTURE 下启用 BYONM

如果您想让您的代码为即将发布的 Deno 2 主要版本做好准备,您可以在您的 shell 或 CI 环境中设置 DENO_FUTURE=1 环境变量。

感谢我们的贡献者!

没有社区的帮助,我们就无法构建 Deno!无论是通过在我们的社区 Discord 服务器 上回答问题,还是通过 报告错误,我们都对您的支持表示衷心的感谢。特别是,我们要感谢以下为 Deno 1.42 做出贡献的人:Dimitris Apostolou、Don Jayamanne、Eric Long、Kenta Moriuchi、Nano Miratus、Sol Boucher、Viktor Marinho、cui fliter、guangwu、mash-graz、mimikun、tuhana、ud2 和 Łukasz Czerniawski。

您想加入 Deno 贡献者的行列吗?请查看我们的贡献文档,我们将在下次列表中看到您。

信不信由你,上面列出的更改并没有告诉你 1.42 中所有改进的地方。您可以在 GitHub 上查看 Deno 1.42 中合并的所有拉取请求

感谢您关注我们的 1.42 版本发布,希望您喜欢使用 Deno 进行构建!

🍋 新鲜的 2.0 版本即将发布。

我们的下一个主要 Fresh 版本将更简洁,使用更具可组合性的、类似 Express 的 API。 在此处了解更多信息