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 快照用于大幅减少启动时间。这种更紧密的集成使得更容易填充缺少的 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 中的指针一直由指针号(数字或 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
。因此,从之前的版本迁移意味着
- 在使用
Deno.PointerValue
来标记 64 位整数而不是指针的地方,用number | bigint
替换它的使用。 - 用
null
替换作为空指针的 0。 - 用
Deno.UnsafePointer.offset(pointer, offset)
使用替换指针运算。
在必须将指针号转换为指针的地方(例如从 TypedArray 获取指针),使用 Deno.UnsafePointer.create(address)
。
Deno
API 的更改
对 API 稳定化
此版本稳定了两个 API:Deno.Command
和 Deno.osUptime()
。这意味着使用这些 API 时不再需要 --unstable
标志。
我们建议用户从 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 以取消正在进行的操作。
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/[email protected]/node/fs.ts
),或者使用内置的 Node 模块说明符 (import fs from "node:fs"
)。
std/http/file_server.ts
在 Deno Deploy 中变得更高效
std/http/file_server.ts
是标准模块中的文件服务器实现。它可以在 Deno 和 Deno Deploy 中使用,这得益于 这两个运行时中 FS API 的兼容性。
但是,由于 Deno Deploy 中的 文件无法使用 mtime
属性,文件服务器无法返回 304
响应来响应对同一资源的请求,并且在多次提供相同的大型资源时,站点速度可能会很慢。
在本版本中,文件服务器已添加对 Deno Deploy 环境中 ETag
标头的支持。它现在可以正确地返回 304 响应来响应对同一资源的请求,并且由文件服务器提供的站点已得到大幅优化。
V8 11.0
本版本升级到最新版本的 V8 (11.0,之前为 10.9)。