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

Deno 1.46:最后一个 1.x 版本

Deno 的目标是提升人们编写 JavaScript 的方式,通过提供 原生 TypeScript 支持一体化工具链Web 标准 API 支持 以及 默认安全的代码执行

Deno 1.46(我们最终的 1.x 版本)继续朝着这一愿景前进,通过 简化 CLI,实现 更短的调用方式简短的权限标志,启用 使用 deno serve --parallel 的多线程 Web 服务器,并添加了众多 Node.js/npm 兼容性改进(包括对 playwright@google-cloudmysql2pglitessh2 等的支持)。

除了这些突出的更新,1.46 还带来了 更好的依赖管理(使用 deno removedeno clean)、用于 deno compile 的代码签名,以提高软件可移植性,以及新添加的 deno fmt 中 HTML、CSS、YAML 等的支持

要升级到 Deno 1.46,请在您的终端中运行以下命令

deno upgrade

如果 Deno 尚未安装,请运行以下命令之一进行安装,或者 在此处了解如何安装

# Using Shell (macOS and Linux):
curl -fsSL https://deno.land/install.sh | sh

# Using PowerShell (Windows):
iwr https://deno.land/install.ps1 -useb | iex

Deno 1.46 的新功能

更简单的 CLI

此版本对 deno CLI 进行了重大更新。

更短的调用方式

此版本带来了一个长期以来用户一直要求和期待的更改,即运行 Deno 程序的方式。

denodeno run 已更改,为执行常见任务提供了更符合人体工程学的方式。

您现在只需使用 deno 即可运行程序,无需再指定 run 子命令

# Deno v1.45
deno run hello.ts
Hello world 🦕

# Deno v1.46
deno hello.ts
Hello world 🦕

您仍然可以将所有必要的标志传递给 deno 子命令

# Deno v1.45
deno run --allow-read main.ts
Reading ./log.txt...

# Deno v1.46
deno --allow-read hello.ts
Reading ./log.txt...

另一个符合人体工程学的设计是使用 deno run 运行任务的能力

// deno.json
{
  "tasks": {
    "test": "deno test --allow-read --allow-net"
  }
}
# Deno v1.45
deno task test

# Deno v1.46
deno run test

这可能是一个微小的改变,但肌肉记忆是真实存在的!对于那些多年来一直使用 npm run <script> 运行任务的用户来说,这将是一个改变游戏规则的设计。

⚠️ v1.45 之前的行为仍然受支持。您仍然可以使用 deno taskdeno run,就像在以前的版本中一样。这些更改是为了那些习惯于将第一个参数作为脚本执行的其他脚本环境的用户而设计的。

简短的权限标志

Deno 的权限系统是 Deno 附带的最重要功能之一。--allow-*--deny-* 标志对于限制对系统部分的访问很有用。由于它们的冗长性,许多用户选择使用 --allow-all 标志,或者更准确地说,是它的简写形式 -A

在 Deno v1.46 中,您现在可以使用大多数常用权限标志的单字母变体

--allow-read -R
--allow-write -W
--allow-env -E
--allow-net -N
--allow-sys -S

这些简写标志接受允许列表,就像长版本一样 - 例如 -R=./static-E=DEBUG,LOG-N=deno.com

如果您不想提供允许列表,可以将它们组合在一起 - 例如 -RWN 将启用 readwritenet 权限。

以下是一些关于如何缩短 CLI 调用方式的示例

# Deno v1.45
deno run --allow-read=./static --allow-env --allow-net=myapi.example.com main.ts

# Deno v1.46
deno run -R=./static -E -N=myapi.example.com main.ts

# Deno v1.46 without `run` subcommand
deno -R=./static -E -N=myapi.example.com main.ts
# Deno v1.45
deno run --allow-read --allow-write --allow-env --allow-sys main.ts

# Deno v1.46
deno run -RWES main.ts

# Deno v1.46 without `run` subcommand
deno -RWES main.ts

新的帮助输出

CLI 选项标志现在按类别逻辑分组

Help output for `deno test` subcommand

deno test 子命令的帮助输出

权限提示现在链接到与相关权限标志相关的文档

Permission prompt links to Deno docs

权限提示链接到 Deno 文档

deno help <subcommand>

`deno help task`

`deno help task`

--allow-* 标志帮助输出

权限标志的帮助文本已更新,包括示例用法。

Permission flags help output

权限标志帮助输出

--env 重命名为 --env-file

--env 标志提供“dotenv”功能,该功能从指定的文件中读取环境变量,并在执行 JavaScript 代码之前为进程设置它们。它非常方便,所有流行的 JS 运行时都提供了此功能。为了与其他运行时保持一致并便于迁移,--env 标志已重命名为 --env-file。旧的标志将继续起作用,但不会在帮助输出中显示。

新的进度条

一直以来,我们收到的反馈是,Deno 有时看起来卡住了,无法下载依赖项。实际上,问题很多 - 网络连接不佳、包注册表限制速率等等。也就是说,没有交互式指示来表明 Deno 正在执行某些任务,这对那些急于开始编写代码的用户来说没有帮助。

为了明确地表明 Deno 仍在工作,我们更新了进度条,以提供更多交互性

Deno v1.45

Deno v1.46

deno checkdeno cache 命令参数中的通配符支持

Deno v1.34 在配置文件和 CLI 标记中添加了对通配符的支持。此通配符功能已扩展到大多数 Deno 子命令,现在您可以在 deno checkdeno cache 子命令中享受通配符扩展。

⚠️ 确保将通配符放在引号中。 否则您的 shell 将扩展它而不是 Deno,这可能会导致由于通配符实现差异而产生的细微错误。

# Type-check all `.ts` files in the current directory and its descendants
deno check "*/**/*.ts"

# Cache all JS files in the current directory
deno cache "*.js"

更快的 deno serve

deno serve 在 Deno v1.43 中引入,并收到了很多正面反馈。此版本为 deno serve 带来了几个非常受欢迎的更改。

1. 开发

通过添加 deno init --serve 选项,您可以在 10 秒内启动服务器。

示例项目包括使用 @std/http 进行路由,以及集成的文件服务器以高效地提供静态资源。

$ deno init --serve
$ deno serve -R main.ts
Listening on https://127.0.0.1:8000
$ curl https://127.0.0.1:8000/hello

此子命令旨在成为一个快速的原型工具,您可以随着项目的增长而扩展它,它并不意味着要取代像 Fresh 这样的框架。

2. 类型检查

deno serve 的局限性之一是它复杂的设置才能正确地类型检查入口文件。使用 Deno v1.46 和最新的 TypeScript 功能,这现在变得容易了:只需在入口文件的 default export 中添加 satisfies Deno.ServeDefaultExport

// server.ts
export default {
  fetch(req) {
    console.log(req.RequestDoesntHaveThisPropery);
    return new Response("Hello world!");
  },
} satisfies Deno.ServeDefaultExport;

如果您对该文件进行类型检查,Deno 会警告任何 API 兼容性问题。

$ deno check server.ts
Check file:///dev/server.ts
error: TS2339 [ERROR]: Property 'RequestDoesntHaveThisPropery' does not exist on type 'Request'.
    console.log(req.RequestDoesntHaveThisPropery);
                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    at file:///dev/server.ts:3:21

请注意,当您构建新的服务器项目时,deno init --serve 会自动将 satisfies Deno.ServeDefaultExport 添加到您的 deno serve 入口点。

3. 扩展

deno serve 子命令提供支持的 Deno.serve() API 非常快。但它默认只使用一个线程。这是有道理的,因为 JavaScript 是一种单线程语言,前提是您不使用像 new Worker() 这样的 API。但是现代服务器拥有多个核心,应该利用它们来实现资源的最有效利用。

为了帮助您在可用资源的基础上实现最佳性能,deno serve 现在支持 --parallel 标记,它允许您通过利用 CPU 的多个核心在多个线程上运行服务器。

$ deno serve --parallel main.ts
deno serve: Listening on http://0.0.0.0:8000 with 10 threads

您可以使用 DENO_JOBS 环境变量指定要使用的线程数量。如果您没有指定此变量,它将默认为机器提供的线程数量。例如,要将线程数限制为 4,您可以运行

$ DENO_JOBS=4 deno serve --parallel main.ts
deno serve: Listening on Listening on http://0.0.0.0:8000 with 4 threads

这里没有魔法——Deno 只是运行 X 个相同的服务器副本,让每个线程成为一个单线程的 JavaScript 运行时。这使得推理应用程序的状态变得更加简单,因为本地扩展的行为与云中扩展的行为相同。

了解更多关于此功能是如何工作的,请查看 关于并行化 deno serve 的 Deno 演讲

deno fmt 现在支持 HTML、CSS、YAML 等等

此版本对 Deno 内置格式化程序 deno fmt 进行了重大升级。

deno fmt 现在可以用于格式化 HTML、CSS、SCSS、Sass、Less、YAML、Astro、Angular、Svelte 和 Vue 文件。

让我们格式化此 HTML 文件

// index.html
<!DOCTYPE html>
<html lang="en">
<head>
            <meta charset="UTF-8">
 <title>Hello `deno fmt`</title>
</head>
<body>
      <h1>Hello <pre>
          deno fmt!
      </pre></h1>
    </body></html>
$ deno fmt --unstable-html index.html
$ cat index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Hello `deno fmt`</title>
  </head>
  <body>
    <h1>Hello <pre>
          deno fmt!
      </pre></h1>
  </body>
</html>

由于这是对 deno fmt 的重大更改,因此在这些新格式中的格式化目前尚不稳定。为了在 deno fmt 中启用这些新格式,需要传递 --unstable-* 标记或在 deno.json(c) 文件中添加选项。请注意,当启用这些选项时,deno fmt 会自动拾取相应的文件。

使用 CLI

# format HTML
$ deno fmt --unstable-html index.html

# format CSS/SCSS/Sass/Less
$ deno fmt --unstable-css styles.css

# format YAML
$ deno fmt --unstable-yaml config.yml

# format component files
$ deno fmt --unstable-component App.vue App.svelte

使用配置文件

// deno.json
{
  "unstable": [
    "fmt-html",
    "fmt-css",
    "fmt-yaml",
    "fmt-component"
  ]
}
$ deno fmt index.html styles.css config.yml App.vue App.svelte

非常感谢 Pig Fang 提供这些格式化程序!

导入断言已弃用

Deno 在 v1 中附带了导入断言提案,允许您导入 JSON 文件

// main.js
import data from "./data.json" assert { type: "json" };
console.log(data);

此后,该提案经历了重大变化,包括将关键字从 assert 更新为 with,并更名为 导入属性

在 Deno 2 中,将不再支持导入断言。为了帮助您迁移到导入属性,从 Deno v1.46 开始,将为每次使用 assert 关键字打印警告,该关键字应替换为 with 关键字。

// data.json
{
  "deno": "2"
}
$ deno run main.js
⚠️  Import assertions are deprecated. Use `with` keyword, instead of 'assert' keyword.

import data from "./data.json" assert { type: "json" };

  at file:///dev/main.js:1:31

{ deno: "2" }

让我们将 assert 更改为 with

// main.js
import data from "./data.json" with { type: "json" };
console.log(data);
$ deno run main.js
{ deno: "2" }

依赖项管理

Deno v1.46 带来了对依赖项管理的几项改进。

deno add 现在支持 dist 标记并建议 npm

您现在可以在添加 npm 依赖项时使用 dist 标记,例如使用 deno add npm:ajv@latest 来拉取 ajvlatest 标记。

此外,当您尝试添加仅在 npm 上可用的 JSR 包时,deno add 现在将提供一个有用的消息。

$ deno add ajv
error: jsr:ajv was not found, but a matching npm package exists. Did you mean `deno add npm:ajv`?

deno remove

根据大家的要求,deno 现在拥有一个子命令来从您的配置文件和锁文件中删除依赖项。

$ deno remove @std/assert @std/path
Removed @std/assert
Removed @std/path

请记住,这些包仍将保留在全局缓存中以备将来使用。如果您想彻底清理环境,请查看 deno clean

deno clean

Deno 拥有一个全局缓存,您可以使用 DENO_DIR 环境变量 来控制它。此缓存用于存储远程依赖项,以便在多个项目中高效使用,V8 代码缓存以加快启动速度,以及用于子命令(如 deno fmtdeno lint 等)的缓存,以最大限度地减少每次运行时完成的工作。

现在您可以通过调用 `deno clean` 快速清除整个缓存。


`deno clean` 子命令的演示

为 `deno compile` 代码签名

由 `deno compile` 生成的程序现在可以进行代码签名。

deno compile app.ts

# on macOS use `codesign` tool
codesign --sign ./app

# on Windows use `signtool`
signtool sign /fd SHA256 .\app.exe

除此之外,为 Windows 编译的程序可以拥有自定义图标。

deno compile --icon=./icon.ico game.tsx

最后,权限提示已调整,以便在遇到缺少权限时提供更有帮助的错误消息。

// app.js
console.log(Deno.readTextFileSync("./log.txt"));
# compile with no permissions
deno compile ./app.js

./app
Requires read access to ./log.txt, specify the required permissions during compilation using `deno compile --allow-read`

# compile again with suggested permissions
deno compile --allow-read ./app.js

./app
Hello world!

关于 `deno compile` 的 Deno 演讲 中了解有关此最新更新的更多信息。

`deno publish` 帮助确保包已获许可

为了确保包已正确获得许可,`deno publish` 现在在发布包时需要许可字段和/或文件。

> deno publish
error[missing-license]: missing license field or file
 --> deno.json
  = hint: add a "license" field. Alternatively, add a LICENSE file to the package and ensure it is not ignored from being published

  docs: https://jsr.deno.org.cn/go/missing-license

error: Found 1 problem

要解决此问题,请在您的 deno.json 或 jsr.json 文件中添加 `"license"` 字段。

{
  "name": "@deno/add",
  "version": "1.0.0",
  "license": "MIT", // add this and/or include a LICENSE file
  "exports": "./mod.ts"
}

`deno upgrade` 改进

`deno upgrade` 是一个便捷的方式,可以让你及时使用 Deno 的最新版本或“canary”版本。

此版本使它更加方便,一旦你升级到 Deno v1.46.0,你就可以舍弃任何 CLI 标志,转而使用

# upgrade to latest stable release
$ deno upgrade

# upgrade to a specific version
$ deno upgrade v1.46.0

# upgrade to latest canary release
$ deno upgrade canary

# upgrade to a specific release
$ deno upgrade 526f39fbb9dacce12c69d24a55798d0bde8f2707

此外,我们添加了一个新的发布频道:发布候选频道。我们打算在发布 Deno 2 之前提供多个发布候选版本。

你可以通过运行以下命令来试用它:`deno upgrade rc`,但请注意,目前只有 v1.46.0 发布候选版本可用。

请关注我们的 Twitter 帐户,获取有关 Deno 2 发布候选版本的消息。

Node.js 和 npm 兼容性

此版本在 Deno 与 Node.js 和 npm 包的兼容性方面带来了许多改进。本周期专注于让几个很受欢迎的包正常工作,这些包是大家强烈要求的。


对 Node.js 和 npm 支持的其他更改包括

性能改进

Deno v1.46 带来了几个性能改进。

测试和覆盖率改进

此版本对 `deno test` 和 `deno coverage` 做了以下改进。

  • `deno coverage --html` 现在显示面包屑,方便导航。

Breadcrumbs navigation in `deno coverage` HTML report

`deno coverage` HTML 报告中的面包屑导航。
  • `deno test` 获得了一个新的 `--hide-stacktraces` 标志,它将在测试失败时禁用打印错误堆栈跟踪。

  • `deno test` 中的 `--allow-none` 标志已重命名为 `--permit-no-files`。我们打算在 Deno 2 中弃用旧标志,因此,如果你依赖它,请确保更新你的脚本!

更简单的冻结锁定文件

Deno v1.46 中引入的冻结锁定文件 是一种简单方便的方式,可以确保 Deno 在向锁定文件添加新依赖项时出错。

此版本使确保项目中的每个人都使用此选项变得更容易,方法是在配置文件中指定以下内容

{
  "lock": {
    "frozen": true
  }
}

任何时候更新依赖项,这将更改锁定文件,Deno 将抛出错误,要求你显式传递 `--frozen=false` 标志,使添加依赖项成为你端的一个有意识的决定。


此外,为了节省带宽和检查 `git diff` 所需的时间,锁定文件格式将在 Deno 2 中变得更加简洁。

你可以使用 `DENO_FUTURE=1` 环境变量来试用它。但是,请注意,切换回不使用 `DENO_FUTURE` 将需要重新生成锁定文件。

文件监视器

热模块替换,在 Deno v1.38 中添加, 现在在 --watch-hmr 标志下被认为是稳定的。 它将出现在相关子命令的帮助输出中 --watch 标志旁边。

此外 deno test 获得了对 --watch=<PATHS> 标志的支持,它允许您传递额外的文件路径以供监视更改并触发测试重新运行。

Web APIs

Deno v1.46 为 Web APIs 带来了两个显著的补充

  • AsyncIterable<T> 现在可以用来构建 RequestResponse 类的主体。 例如,来自 node:fscreateReadStream 是一个实现了 AsyncIterable 协议的 API,因此它可以与 fetch API 一起使用,如下所示
const file = createReadStream("./fixture.json");

const response = await fetch("http://example.com", {
  method: "POST",
  body: file,
});

Deno 现在将随着数据的可用(从磁盘读取)而流式传输数据,以实现高效的 HTTP 调用。

  • URLPattern API 现在支持 ignoreCasehasRegExpGroups。 前者允许不区分大小写的模式匹配
const pattern = new URLPattern({
  pathname: "/foo/bar",
}, {
  ignoreCase: true,
});
pattern.test("/foo/bar"); // true
pattern.test("/fOo/BaR"); // true

hasRegExpGroups 属性可以让您知道模式是否使用任何正则表达式组

const pattern = new URLPattern({
  pathname: "/foo/bar/(.+)",
});
pattern.hasRegExpGroups; // true

标准库是稳定的

Deno 标准库 提供了一套高质量的包,涵盖数据解析和操作、使用网络协议以及核心团队审核并保证与 Deno 兼容的一般实用程序。

我们很高兴地宣布我们已经完成了 我们的稳定过程,有 30 个包达到 v1 或更高版本。

  1. std/assert
  2. std/async
  3. std/bytes
  4. std/cli
  5. std/collections
  6. std/crypto
  7. std/csv
  8. std/data-structures
  9. std/encoding
  10. std/expect
  11. std/fmt
  12. std/front-matter
  13. std/fs
  14. std/html
  15. std/http
  16. std/json
  17. std/jsonc
  18. std/media-types
  19. std/msgpack
  20. std/net
  21. std/path
  22. std/regexp
  23. std/semver
  24. std/streams
  25. std/testing
  26. std/text
  27. std/toml
  28. std/ulid
  29. std/uuid
  30. std/yaml

为了分享使用标准库中的模块可以做些什么,我们发布了 一条推文串,每条推文包含一个模块的代码示例。

如果您想了解更多关于我们的标准库的信息,请查看我们的 3 分钟短片

V8 12.9

Deno 1.46 附带最新的 V8 12.9。

鸣谢

没有我们社区的帮助,我们无法构建 Deno! 无论是在我们的社区 Discord 服务器 上回答问题,还是 报告错误,我们都非常感谢您的支持。 特别感谢以下人员对 Deno 1.46 的贡献:Andreas Deininger、Bedis Nbiba、Birk Skyum、Hajime-san、HasanAlrimawi、Ian Bull、Igor Borisoglebski、Ivancing、Kenta Moriuchi、Kyle Kelley、MrEconomical、MujahedSafaa、Pig Fang、Rano | Ranadeep、Roy Ivy III、Sean McArthur、Yazan AbdAl-Rahman、Zebreus、chirsz、i-api、melbourne2991、seb、vwh 和 Łukasz Czerniawski。

您想加入 Deno 贡献者的行列吗? 查看我们的贡献文档,下次您就会出现在列表中。

信不信由你,上面列出的更改仍然没有告诉你 1.46 中变得更好的所有内容。 你可以查看在 Deno 1.46 中合并的完整拉取请求列表 在 GitHub 上

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

接下来是什么?

🚨️ Deno 2 即将发布 🚨️

几天后,Deno 2 的第一个“发布候选版本”将发布。

Deno 2 中有一些 轻微的重大更改

您可以使用 deno upgrade rc 获取它,但您现在就可以通过添加 DENO_FUTURE=1 环境变量来防范您的代码。