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

Deno 1.45: 工作区和单仓库支持

Deno 继续发展,发布了 Deno 1.45。此版本最突出的功能是引入了工作区,为管理单仓库提供了强大的解决方案。此新增功能简化了大型代码库中的依赖项管理、配置共享和模块组织。除了工作区之外,此更新还包括对 Node.js 兼容性的改进、对 `deno install` 的更新、新的 `deno init --lib` 命令、`deno vendor` 的弃用等等。

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

deno upgrade

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

# Using Homebrew (macOS):
brew install 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.45 中的新增功能

工作区支持

Deno v1.45 添加了对工作区和单仓库的支持。支持两种工作区形式:在 `deno.json` 中定义的 Deno 首选工作区和向后兼容的 npm 工作区。

Deno 工作区非常简单。全局定义的配置将应用于每个成员包,但可以被成员包覆盖。您可以混合使用 npm 和 Deno 工作区,例如 Deno 工作区中的 npm 包或反之亦然。

将工作区成员发布到 JSR 非常简单,只需运行 `deno publish` 即可。 标准库 是有效使用工作区的良好示例。

要开始使用,请在您的 `deno.json` 中定义一个 `"workspace"` 元素,并列出成员目录。

{
  "workspace": ["./add", "./subtract"]
}

npm 工作区 在 Deno 中也可以无缝使用。无论您是在更大的 npm 工作区中包含 Deno 库,还是在更大的 Deno 工作区中包含 npm 库,依赖项都将正确解析。

要详细了解工作区支持,请访问Deno 文档

我们还将在 7 月 16 日星期二太平洋时间上午 9 点(UTC-7)举办一场YouTube 上为期一小时的直播,详细介绍我们的新工作区支持并回答您的问题。 点击此处报名

Node.js 兼容性改进

Node-API 支持已完全更新,修复了 `prisma`、`sqlite3`、`paper`、`duckdb`、`nodejs-polars` 等软件包中存在的许多问题。

其他 Node.js 兼容性改进包括

此外,还有其他与 `npm` 支持相关的改进

冻结锁文件

添加了一个新的 `--frozen`(别名 `--frozen-lockfile`)标志,用于控制锁文件的行为。

您可以使用此标志告诉 Deno 在锁文件过时时始终报错。这在 CI 管道中特别有用,您应该确保所有推送的代码都是最新的,并且依赖项没有新的或意外的更改。

在使用 `--frozen` 标志运行 deno 命令时,任何尝试使用新内容更新锁文件的行为都将导致命令退出,并显示将进行的修改所导致的错误。

例如,假设您的项目中某个地方导入的是 `npm:[email protected]`。之后,某人从略微过时的 AI 聊天机器人中复制了一段代码,该聊天机器人只知道 chalk 版本 `5.2.0`,因此某个文件中最终会有一个类似以下的导入

import chalk from "npm:[email protected]";

幸运的是,您的 CI 管道有一个使用 `--frozen` 指定的测试步骤

deno test --frozen --coverage

它不会静默地将 chalk 的第二个(过时的)版本添加到您的依赖项树中,而是会失败,并显示将 chalk 5.3.0 添加到您的锁文件中

error: The lockfile is out of date. Run `deno cache --frozen=false` or rerun with `--frozen=false` to update it.
changes:
 5 | -      "npm:[email protected]": "npm:[email protected]"
 6 | -    },
 7 | -    "npm": {
 5 | +      "npm:[email protected]": "npm:[email protected]",
 6 | +      "npm:[email protected]": "npm:[email protected]"
 7 | +    },
 8 | +    "npm": {
 9 | +      "[email protected]": {
10 | +        "integrity": "sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==",
11 | +        "dependencies": {}
12 | +      },

如果您打算显式更新您的锁文件,您可以指定 `--frozen=false`,这将在没有错误的情况下更新锁文件。

使用上述设置,每次依赖项更新都需要运行使用 `--frozen=false` 标志的命令或任务,从而使这些更新成为有意且明确的操作。

最后,`--lock-write` 现在已弃用,将在 Deno 2 中删除。您可以将 `--lock-write` 的用法替换为 `--frozen=false`。

deno install 更新

在 Deno 2 中,deno install 子命令的行为将更像 npm install 以支持常见的开发流程。目前在 Deno 中,deno install <pkg> 会全局安装二进制包。在 Deno 2 中,deno install <pkg> 默认情况下会本地安装包,将新的依赖项添加到项目中(类似于 deno add <pkg>)并进行缓存。此外,deno install 不带参数将缓存 package.json 或导入映射中列出的本地依赖项,并设置一个本地 node_modules 目录(如果适用)。要全局安装,您需要指定 --global (-g) 标志:deno install --global <pkg>

要在您的项目中试用新的安装命令,请使用 DENO_FUTURE=1 运行

DENO_FUTURE=1 deno install

带有参数,类似于 deno add

DENO_FUTURE=1 deno install @david/dax

我们鼓励您尝试新的 deno install 并报告您遇到的任何问题!

npm 生命周期脚本支持

package.json 中的某些脚本是特殊的,因为它们在某些操作时会由 npm 自动执行。npm 支持许多生命周期脚本,但作为包的使用者,主要的相关脚本是预安装/后安装脚本,它们在安装包时执行(即通常在 npm install 期间)。

一些包依赖于它们的安装脚本执行设置步骤(例如,下载或构建原生插件的工件),如果它们没有执行,则无法正常工作。以前,Deno 不支持执行生命周期脚本,因此这可能会导致在使用某些包时出现令人困惑的错误,而且没有简单的解决方案。

现在,Deno 支持在 deno cache(以及 DENO_FUTURE=1 deno install)中运行生命周期脚本,如果它检测到包具有未运行的生命周期脚本,则会发出警告。

通过使用 deno cache(或 DENO_FUTURE=1 deno install)指定 --allow-scripts 标志,您可以选择为特定包运行生命周期脚本

deno cache --allow-scripts=npm:duckdb main.ts

ℹ️ 注意
目前,我们只支持在使用本地 node_modules 目录(deno.json 中的 "nodeModulesDir": true)时使用生命周期脚本。

将来,我们计划添加对没有 node_modules 的生命周期脚本的支持,但这将是尽力而为的,因为某些包依赖于位于 node_modules 目录中。

deno init --lib - 轻松设置新的库

deno init 子命令在 Deno v1.25 中引入,允许您用几个按键启动 Deno 项目的最小脚手架。

自从 JSR 引入以来,用户一直在要求一种快速启动将发布到 JSR 的项目的方法。

您只需使用 Deno v1.45 和 deno init --lib 即可做到这一点

✅ Project initialized

Run these commands to get started

  # Run the tests
  deno test

  # Run the tests and watch for file changes
  deno task dev

  # Publish to JSR (dry run)
  deno publish --dry-run

只需确保在发布之前更新生成的 deno.json 文件中的 nameversion 字段!

deno vendor 现已弃用

deno vendor 在 Deno v1.19 中添加 以允许用户将所有依赖项都放入项目目录中。

此后,另一种依赖项引入方式 在 Deno v1.37 中引入,使用 --vendor 标志或配置文件中的 { "vendor": true } 选项。

此选项获得了许多正面反馈,并指出了 deno vendor 子命令的缺点和糟糕的开发体验。考虑到这一点,deno vendor 现在已弃用,并计划在 Deno 2 中删除。

请迁移到使用配置文件中的 --vendor 标志或 vendor 选项。

deno test 文件发现

deno test 可以自动发现并运行与特定模式匹配的文件的测试

  • 文件名以 _test 结尾 - 例如 app_test.tscomponent_test.tsx
  • 文件名以 .test 结尾 - 例如 router.test.tscontroller.test.js
  • 文件名是 test - 例如 test.tstest.js

为了提高与更广泛生态系统的兼容性,deno test 现在将自动发现并运行位于 __tests__ 目录下的文件

$ tree
.
├── __tests__
│   ├── integration.ts
│   └── unit.ts
└── main.ts

2 directories, 3 files

在 Deno v1.44 中

$ deno test
error: No test modules found

在 Deno v1.45 中

$ deno test
deno test
Check file:///Users/ib/dev/test_discovery/__tests__/integration.ts
Check file:///Users/ib/dev/test_discovery/__tests__/unit.ts
running 1 test from ./__tests__/integration.ts
integration test ... ok (0ms)
running 1 test from ./__tests__/unit.ts
unit test ... ok (0ms)

ok | 2 passed | 0 failed (11ms)

Blob.bytes()

继 Deno v1.44 中的更改 以及 Web 文件 API 规范的更新之后,现在支持 Blob.bytes()

const jsonStr = JSON.stringify({ hello: "world" }, null, 2);

// Before:
const blob = new Blob([jsonStr], { type: "application/json" });
const buffer = new Uint8Array(await blob.arrayBuffer());

// After:
const blob = new Blob([jsonStr], { type: "application/json" });
const buffer = await blob.bytes();

Jupyter 笔记本改进

您现在可以在 Jupyter 笔记本中使用 promptconfirm API 来提供更多灵活性和交互性。



为了进一步改善 JavaScript(和 TypeScript)的数据科学生态系统,我们计划在下一个版本中添加使用 JSX 和 React 的交互式小部件支持。

deno compile 支持 --env 标志

--env 标志 在 Deno v1.38 中添加,添加了从 .env 文件加载进程的环境变量的原生支持。

使用 Deno v1.45,--env 标志可用于将某些环境变量包含到使用 deno compile 生成的二进制文件中。

🛑 注意
请记住,这些环境变量仍然可以在检查发布的程序的内容时读取,因此请谨慎使用此功能。将写入二进制文件的生产密钥发布可能不是最好的主意。

在执行使用 deno compile 创建的程序时,对 .env 文件中提供的变量的所有对 Deno.env.get(<var_name>) 的调用将返回编译过程中指定的 value,而不是用户系统上的当前变量

$ cat .env
HELLO_THERE=deno

$ cat main.ts
console.log("Hello there")
console.log(Deno.env.get("HELLO_THERE") + "!");

$ deno compile --env --allow-env main.ts
...

在 Deno v1.44.4 中

HELLO_THERE="General Kenobi" ./main
Hello there
General Kenobi!

在 Deno v1.45.0 中

HELLO_THERE="General Kenobi" ./main
Hello there
Deno!

更灵活的语言服务器

以前,VSCode 扩展只能读取并合并位于工作区根目录的 deno.jsondeno.jsonc 文件。来自那里的配置将应用于每个打开的源文件。这使得某些 monorepo 配置变得不可能。

1.45 使语言服务器更加独立于编辑器中打开的根文件夹。子目录中的配置文件现在会被检测到,即使存在多个配置文件也是如此。每个发现的 deno.jsondeno.jsonc 将产生一个单独的范围,具有自己的类型检查环境、模块解析等等。您可以为 compilerOptions.libs 配置不同的条目,或导入模块,这些模块将对全局类型进行扩展,这些扩展不会污染其他 deno.json[c] 范围的环境。

标准库更接近稳定

Deno 标准库 提供了一组由核心团队审核的优质包,并保证与 Deno 协同工作。

正如我们之前博客文章中所述,标准库目前正在进行稳定工作,目标是稳定 38 个包中的 31 个。

迄今为止,我们已经稳定了 13 个包

  1. @std/assert
  2. @std/bytes
  3. @std/collections
  4. @std/crypto
  5. @std/data-structures
  6. @std/encoding
  7. @std/html
  8. @std/media-types
  9. @std/msgpack
  10. @std/path
  11. @std/regexp
  12. @std/toml
  13. @std/uuid

这些包已达到 1.0.0 版本,遵循 SemVer 语义 并确保它们在 1.x.x 版本中的兼容性。

剩余的 18 个包已发布了它们的发布候选版 (RC) 版本(请参阅路线图问题 获取列表)。如果您目前正在使用任何这些包,请考虑测试 RC 版本并与我们分享您的反馈

有关稳定时间线的更多详细信息,请参阅路线图问题

V8 12.7 和 TypeScript 5.5.2

Deno 1.45 带有 V8 12.7 和 TypeScript 5.5.2

使用 DENO_FUTURE=1 尝试 Deno 2 的功能

我们建议您尝试使用 DENO_FUTURE=1 环境变量运行现有的项目,该变量将启用 Deno 2 的功能。我们预计迁移工作量很小或非常低。如果您的体验不同,请 与我们分享

致谢

没有社区的帮助,我们无法构建 Deno!无论是通过在我们的社区 Discord 服务器 中回答问题,还是 报告错误,我们都非常感谢您的支持。特别感谢以下人员对 Deno 1.45 的贡献:Adam Gregory、Andreas Kohn、Andrew Johnston、Filip Skokan、HasanAlrimawi、Kenta Moriuchi、Luca Bruno、Oliver Medhurst、Richard Carson、Tom Alcorn、Victor Turansky、Yazan AbdAl-Rahman、Zander Hill、Zebreus、muddlebee、safaa-mojahed、ud2。

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

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

感谢您关注我们的 1.45 版本,希望您喜欢用 Deno 构建!