Deno 1.31:package.json 支持
Deno 1.31 已被标记并发布,包含以下新特性和变更
package.json
支持- Node-API 的稳定化
- 兼容性层现在是运行时的一部分
- 远程模块支持 npm 规范符
- FFI API 中的重大变更
Deno
API 的变更- 命令行界面的变更
- 标准库的变更
- V8 11.0
如果您已经安装了 Deno,可以通过运行以下命令升级到 1.31
deno upgrade
如果您是首次安装 Deno
# MacOS and Linux
curl -fsSL https://deno.land/x/install/install.sh | sh
# Windows
iwr https://deno.land/x/install/install.ps1 -useb | iex
点击此处查看更多安装选项。
package.json
支持
此版本带来了一个令人兴奋的新功能 - package.json
支持。Deno 现在更加易于访问,使开发人员能够轻松地从现有的 Node 项目过渡。
Deno 现在将自动检测 package.json
并使用它来安装和解析所使用的依赖项(例如 import express from "express"
)。此外,这使得能够使用 deno task
运行在 scripts
部分中定义的项目特定脚本。
注意:目前对 “scripts” 的支持仅限于简单脚本。像
rimraf
或cross-env
这样的程序将无法工作;我们将在即将发布的版本中添加对此类程序的支持。
例如,假设我们有以下 package.json
{
"name": "@deno/my-example-app",
"description": "An example app created with Deno",
"type": "module",
"scripts": {
"say-hello": "cowsay 'Hello from deno!'"
},
"dependencies": {
"chalk": "^5.2"
},
"devDependencies": {
"cowsay": "^1.5"
}
}
以及以下通过裸标识符引用 chalk 的脚本
// main.ts
import chalk from "chalk";
console.log(chalk.green("Hello from Deno!"));
我们可以运行这个脚本
> deno run --allow-env --allow-sys main.ts
Hello from Deno!
或通过 deno task
执行 package.json 脚本
> deno task say-hello
Task say-hello cowsay 'Hello from deno!'
__________________
< Hello from deno! >
------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
对于更复杂的示例,您可以尝试运行一个示例 Vite 项目
$ deno run -A npm:create-vite vite-project --template vue
$ cd vite-project
$ deno task dev
重要的是要注意,Deno 仍然支持 Web 标准导入映射,这仍然是在 Deno 中映射裸标识符的首选方式。
与往常一样,Deno 致力于使开发尽可能顺畅和高效。我们对这个功能带来的可能性感到兴奋,并热切期待来自社区的反馈。
Node-API 的稳定化
Deno 1.31 稳定了 Node-API(又名 N-API),这意味着在使用依赖于 Node-API 的 npm 包时不再需要 --unstable
标志。
此外,Node-API 还应用了许多错误修复,现在可以使用更多软件包而不会出现问题。我们计划在未来几周内解决剩余的错误。
兼容性层现在是运行时的一部分
Deno 1.31 通过将 Node.js 的兼容性层直接移至 Deno 运行时本身,从而显着改进了运行时。在以前的版本中,Node.js 的兼容性是通过 https://deno.land/std/node
提供的 - 这是在 Deno 标准库的用户代码中实现的一组 polyfill。每次 Deno 发布时,都必须更新对 https://deno.land/std
的依赖,这导致每次升级后都必须下载兼容性层。此外,该层很大(约 1.5Mb),导致重复执行此代码时启动速度进一步减慢。
为了解决这些问题,Deno 团队采取了激进的措施来改善依赖 npm 包的用户的情况 - 通过 npm: 规范符或新添加的 package.json 自动发现。整个兼容性层现在都嵌入在 Deno 运行时本身中,并且 V8 快照用于大幅缩短启动时间。这种更紧密的集成使得更容易 polyfill 缺少的 API,并提高了已支持的内置 Node.js 模块的性能。
要立即使用嵌入式 Node polyfill,您可以从 node: 规范符导入。例如,要导入 Node 的 fs 模块,请从 node:fs 导入。此更改将显着提高 Deno 应用程序的性能,并使 Deno 团队能够更轻松地支持和增强运行时与 Node.js 的兼容性。
远程模块支持 npm 规范符
以前,导入依赖于 npm 包的远程模块需要 --unstable
标志。现在不再需要了。
亲自尝试一下
deno run --allow-env --allow-sys https://gist.githubusercontent.com/dsherret/2273fbf9eb3c3ac73b4862cf6633c4cf/raw/442c6cea52f5a292359963a22fdab7fd7e4133ff/main.ts
FFI API 中的重大变更
自 1.24 以来,Deno 中的指针一直由指针数字(number 或 BigInt)表示,并为此提供了自定义的 Deno.PointerValue
类型。该类型也用作 64 位整数的类型。
从 Deno 1.31 开始,指针现在表示为普通对象,或者对于空指针表示为 null。这些对象由 V8 直接创建,并由 V8 Fast API 支持,这意味着在使用 "pointer"
类型参数和返回值时,FFI 的性能从以前的版本得到了进一步提高。指针对象是不透明的,无法直接从 JavaScript 操作。这意味着 FFI 变得更安全,因为指针欺骗不再像编写 JavaScript 数字那么容易。
这是对尚未稳定的 FFI API 的重大变更。Deno.PointerValue
类型仍然存在,但现在代表 null | PointerObject
,并且 64 位整数参数和返回值现在显式使用类型 number | bigint
。因此,从以前的版本迁移意味着
- 在用于标记 64 位整数而不是指针的地方,将
Deno.PointerValue
的用法替换为number | bigint
。 - 将 0 作为空指针的用法替换为
null
。 - 将指针算术运算替换为
Deno.UnsafePointer.offset(pointer, offset)
用法。
在必须将指针数字转换为指针的地方(例如,从 TypedArray 获取指针),使用 Deno.UnsafePointer.create(address)
。
Deno
API 的变更
API 稳定化
此版本稳定了两个 API:Deno.Command
和 Deno.osUptime()
。这意味着不再需要 --unstable
标志即可使用这些 API。
我们建议用户从 Deno.run()
API 迁移到新的 Deno.Command
API,因为我们计划在未来弃用 Deno.run()
。
稳定 API 的扩展
Deno.build.os
现在返回更多种类的操作系统:"darwin" | "linux" | "windows" | "freebsd" | "netbsd" | "aix" | "solaris" | "illumos"
。虽然其中一些未获得官方支持,但一些用户正在自行编译 Deno,并要求提供扩展的操作系统列表。
Deno.resolveDns()
获取了一个新的 signal
选项,该选项允许传递 AbortSignal
到 API 以取消正在进行的operation。
const ac = new AbortController();
const promise = Deno.resolveDns("www.example.com", "A", {
nameServer: { ipAddr: "127.0.0.1", port: 4553 },
signal: ac.signal,
});
ac.abort();
命令行界面的变更
deno bundle
弃用
deno bundle
命令不再受支持,并且不会显示在帮助输出中。虽然 Deno 没有立即删除它的计划,但鼓励用户切换到其他捆绑解决方案,例如 deno compile
、deno_emit
、esbuild、rollup 或其他。
重要的是要注意,为浏览器捆绑 JavaScript 是一个复杂的过程,有各种选项和观点。deno bundle
不是浏览器捆绑的理想解决方案。它的主要功能是创建一个自包含的文件,用于在 Deno 中运行服务器端代码,但这导致了用户的困惑。
随着 Deno 继续支持 npm 和内置的 Node 模块,支持 deno bundle 变得更加困难。因此,考虑到用户领域中已经有优秀的捆绑器,因此决定从运行时本身删除此功能。
deno bench
的 JSON 报告器
deno bench
现在接受 --json
标志,该标志会将基准测试结果打印为 JSON。这允许以编程方式使用结果。
请注意,格式仍然不稳定,将来可能会更改。
$ deno bench --json bench_me.js
{
"runtime": "Deno/1.31.0 x86_64-apple-darwin",
"cpu": "Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz",
"benches": [
"origin": "file:///dev/bench_me.js",
"group": null,
"name": "Deno.UnsafePointerView#getUint32",
"baseline": false,
"result": {
"ok": {
"n": 49,
"min": 1251.9348,
"max": 1441.2696,
"avg": 1308.7523755102038,
"p75": 1324.1055,
"p99": 1441.2696,
"p995": 1441.2696,
"p999": 1441.2696
}
}
]
}
感谢 Serhiy Barhamon 实现了此功能。
权限提示的改进
从此版本开始,交互式权限提示现在接受新的选项 A
。此选项允许为所有后续调用使用授予域的 API 授予权限。
示例
$ deno repl
Deno 1.31.0
exit using ctrl+d, ctrl+c, or close()
> Deno.env.get("DENO")
┌ ⚠️ Deno requests env access to "DENO".
├ Run again with --allow-env to bypass this prompt.
└ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all env permissions) > A
✅ Granted all env access.
undefined
> Deno.env.get("FOOBAR")
undefined
>
以前这是不可能的,用户必须为每个请求与先前请求的值不同的 API 调用授予权限。这导致必须回答多个提示,而此更改使为某些域授予权限更加符合人体工程学。
感谢 Asher Gomez 实现了此功能。
deno compile
可以与静态可分析的动态导入一起使用
deno compile
现在可以理解在编译时可以解析的动态导入,即采用纯字符串文字的动态导入。
// main.ts
const { add } = await import("./add.ts");
console.log(add(1, 2));
// add.ts
export function add(a: number, b: number) {
return a + b;
}
> deno compile main.ts
Compile file:///V:/example/main.ts
Emit example.exe
> ./example
3
deno fmt
的更短参数
deno fmt
通过 CLI 标志接受了一些选项 - 所有选项都采用 --options-<option_name>
的形式。此版本添加了这些标志的简写版本,省略了标志名称的 “options” 部分。
示例
# before
deno fmt --options-line-width=100 --options-use-tabs=true
# after
deno fmt --line-width=100 --use-tabs=true
旧标志仍然受支持,但它们未包含在帮助输出中。
感谢 aryan02420 实现了此功能。
标准库的变更
此版本标准库的主要更改是删除了 https://deno.land/std/node
模块。此代码已移至主 deno 存储库,现在直接嵌入在 Deno 运行时中。对于依赖于 https://deno.land/std/node
的用户,我们建议将 std 版本固定到 0.177.0
版本 (https://deno.land/std@0.177.0/node/fs.ts
) 或使用内置的 Node 模块规范符 (import fs from "node:fs"
)。
std/http/file_server.ts
在 Deno Deploy 中变得更加高效
std/http/file_server.ts
是标准模块中的文件服务器实现。由于 FS API 在两个运行时中的兼容性,它可以在 Deno 和 Deno Deploy 中工作。
但是,由于 Deno Deploy 中文件 mtime
属性的不可用,文件服务器无法向同一资源的请求返回 304
响应,并且当站点多次提供相同的大型资源时,站点可能会很慢。
在此版本中,文件服务器已添加到 Deno Deploy 环境中对 ETag
标头的支持。现在,它可以为对同一资源的请求正确返回 304 响应,并且由文件服务器提供的站点得到了极大的优化。
V8 11.0
此版本升级到最新版本的 V8(11.0,之前为 10.9)。