跳转至主要内容
Deno 2 终于来了 🎉️
了解更多
Deno 1.28 Release Notes

Deno 1.28:新增 130 万个模块

我们很高兴地宣布,Deno 1.28 稳定了 npm 兼容性,这意味着您现在可以在 Deno 中导入超过 130 万个 npm 模块。 现在您可以使用您最喜欢的持久数据模块,例如 Prisma、Mongoose 和 MySQL,以及前端框架,例如 React、Vue 等,构建应用程序将比以往更容易、更安全。

使用 Deno,npm 更易用、更安全。Deno 的内置工具链、一流的标准库和强大的 IDE 支持意味着您可以更快地提高生产力。 而且 Deno 默认安全的、选择加入的权限模型意味着您可以减少担心可疑软件包的时间,而将更多时间用于交付产品。

Deno 坚持认为现代 JavaScript 应该使用 ES 模块和 Web 标准 API 构建。此版本不会改变这一点。导入 npm 模块是通过 URL 以符合标准的方式完成的——我们继续朝着浏览器兼容的未来迈进,在其中您将使用 Web API,例如 fetchRequestResponse。现在,Deno 通过允许您在现代、安全的编程环境中访问您最喜欢的模块,使 npm 更进一步。

为了帮助您开始在 Deno 中使用 npm 模块,我们将在本周每天发布资源、操作指南等。请务必关注我们的 Twitter订阅我们的 YouTube 以便及时了解。

在本篇文章中

安装或升级 Deno

如果您已经安装了 Deno,可以通过运行以下命令升级到 1.28

deno upgrade

如果您是第一次安装 Deno

# MacOS and Linux
curl -fsSL https://deno.land/install.sh | sh

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

点击此处 获取更多安装选项。

使用 npm

您可以通过导入 npm: 说明符来使用 npm 包。

在导入语句中

import { chalk } from "npm:chalk@5";

或者在 导入映射 中将一个裸说明符映射到一个 npm 说明符

{
  "imports": {
    "chalk": "npm:chalk@5"
  }
}

您还可以使用 Deno 运行 npm 脚本或 CLI

deno run --allow-env --allow-read npm:create-vite-extra

您甚至可以使用如下子命令执行 npm 包

deno run npm:<package_name> <subcommand>

例如,Deno 中 npx prisma init 的等效命令是

deno run npm:prisma init

安全性

虽然 npm 使软件易于使用和共享,但未经检查的安装和运行依赖项的方法使 Node 和 npm 易受供应链攻击。 通过域名抢注社会工程和其他漏洞利用,恶意模块可以上传然后安装到生产 Node 应用程序中,从而危及数百万用户及其敏感数据。

Deno 默认安全的方法不是允许不受信任的第三方代码访问您的整个系统,而是在您的依赖项尝试访问系统时通知您并进行限制。

deno run npm:install-malware
⚠️  ┌ Deno requests write access to /usr/bin/.
   ├ Requested by `install-malware`
   ├ Run again with --allow-write to bypass this prompt.
   └ Allow? [y/n] (y = yes, allow; n = no, deny) >

了解有关 Deno 选择加入权限系统的更多信息.

无需 package.json

在 Deno 中使用 npm 更简单

  • 无需 npm install 步骤:模块会在您第一次运行程序时安装。
  • 无需 package.json:减少代码库中的样板文件噪音。
  • 默认情况下没有 node_modules 文件夹(使用 --node-modules-dir 以实现向后兼容)。模块会在一个特殊的全局目录中缓存一次。

使用 Deno 立即提高生产力。借助内置工具链(包括测试器、格式化程序、linter 等)和原生 TypeScript 支持,您可以跳过安装和配置依赖项的步骤,直接深入代码。

正在进行的工作

我们的目标是使尽可能多的 npm 模块与 Deno 兼容。由于一些我们尚未遇到的边缘情况、安装后脚本或一些包对在具有典型 Node 设置的文件夹中执行的假设(例如,假设当前工作目录中存在 package.json),某些模块可能(尚)不兼容。

我们将在接下来的几个月里努力解决这些问题并提高我们的兼容性。例如,我们目前重新利用了 Node 的一些测试套件,以确保我们的 Node 兼容层(例如 fs 等模块)与 Node 的工作方式相同,并且我们将扩大此覆盖范围。我们也在积极修复社区提出的任何边缘情况。

Deno 中的某些子命令(如 deno compile)尚不适用于 npm 模块。这项工作正在 deno#15960 中跟踪。

为了帮助我们提高与 npm 的兼容性,如果您在 Deno 中使用 npm 时遇到任何问题,请提交问题。我们相信,随着使用量的增加,我们将弥合大多数剩余的兼容性差距。

自动发现锁文件

Deno 自 v1.0 起就支持锁文件,但是使用它们的体验有很多不足之处 - 使用锁文件始终是用户的责任,需要提供 --lock=<filename> 标志。我们意识到这种情况导致许多用户根本不使用锁文件。

从 Deno v1.28 开始,如果发现配置文件 (deno.json(c)),将自动发现并使用锁文件。在这种情况下,将自动在配置文件旁边创建一个名为 deno.lock 的锁文件(如果尚不存在)。如果新的依赖项成为模块图的一部分,锁文件将自动并增量更新。

因此,--lock-write 标志的行为已针对此自动发现场景进行了扩展 - 不再需要传递此标志来更新锁文件,现在可以使用它来强制从头开始生成锁文件。

如果您希望禁用锁文件的自动发现,可以使用 --no-lock 标志。

此外,--lock 标志默认不再需要参数 - 如果省略它,则 Deno 将默认为 ./deno.lock

对 `Deno` API 的更改

稳定性

此版本中以下 API 已稳定,不再需要使用 --unstable 标志。

  • Deno.bench()
  • Deno.gid()
  • Deno.networkInterfaces()
  • Deno.systemMemoryInfo()
  • Deno.uid()

新的不稳定 Deno.Command API

此版本添加了新的统一 Deno.Command API,以取代不稳定的 Deno.spawnDeno.spawnSyncDeno.spawnChild API。

基本的异步用法

let c = new Deno.Command("echo", { args: ["foo"] });
let { stdout, stderr } = await c.output();

基本的同步用法

let c = new Deno.Command("echo", { args: ["foo"] });
let { stdout, stderr } = c.outputSync();

高级异步用法(带流式传输)

const c = new Deno.Command("cat", { stdin: "piped" });
c.spawn();
// open a file and pipe input from `cat` program to the file
const file = await Deno.open("output.txt", { write: true });
await c.stdout.pipeTo(file.writable);

const stdin = c.stdin.getWriter();
await stdin.write(new TextEncoder().encode("foobar"));
await stdin.close();

const s = await c.status;
console.log(s);

V8 10.9

此版本升级到 V8 的最新版本(10.9,之前是 10.8)。这些主要是内部改进,但也包括一些面向公众的 API 更改

10.8 和 10.9 之间的完整更改列表在此处

手动重写

随着 Deno 的发展,手册也随之发展。我们不断地在这里和那里添加内容;随着时间的推移,这导致它变得有点凌乱。在这个版本中,我们对目录和内容进行了全面重构,使其更简单、更有条理。我们甚至添加了一个专门用于使用 npm 的完整章节

文档总是有改进的空间——如果您发现可以改进的地方,请提交 PR 至 denoland/manual

发布周

为了展示您现在可以使用 npm 和 Deno 构建的内容,我们本周每天都会发布教程、操作指南、YouTube 视频演示以及其他有用的资源。

如果您在商业环境中使用 Deno 并有任何技术问题,请注册办公时间,您将有机会与我们的工程师交流,他们将为您提供 30 分钟的帮助来解决您的问题。

关注我们的 Twitter订阅我们的 YouTube 频道,这样您就不会错过任何内容!