Node.js 20 正式发布!
4 月 18 日,Node.js 正式发布了 20 版本,新版中的亮点包括全新的 Node.js 权限模型、同步的 import.meta.resolve
、稳定的测试运行器、更新 V8 JavaScript 引擎到 11.3,Ada 到 2.0 等!
下载:https://nodejs.org/en/download/current/
注意,Node.js 20 将在 10 月份进入长期支持(LTS)期,在那之前,它将在接下来的六个月内成为“Current”版本。鼓励探索这个最新版本提供的新功能和好处,并评估它对应用的潜在影响。
权限模型
Node.js 权限模型是一种实验性机制,用于在执行期间限制对特定资源的访问。在这个第一个包含权限模型的发布版本中,这些功能带有以下能力:
限制对文件系统的访问(读和写),使用 --allow-fs-read
和--allow-fs-write
命令;限制对 child_process
的访问,使用--allow-child-process
命令;限制对 worker_threads
的访问,使用--allow-worker
命令限制对原生插件的访问(与 --no-addons
标志相同)
可用权限由
--experimental-permission
标志记录。
使用 --experimental-permission
启动 Node.js 时,将限制访问文件系统、生成进程和使用 node:worker_threads
的能力。
使用 Node.js 的开发人员现在可以更好地控制文件系统访问,因为引入了 --allow-fs-read
和 --allow-fs-write
标志。这些实验性功能允许更细粒度地控制 Node.js 进程可以访问文件系统的哪些部分。
要启用这些标志,可以使用 --experimental-permission
标志和所需的权限。例如,运行以下命令允许对整个文件系统进行读写访问:
node --experimental-permission --allow-fs-read
还可以通过将逗号分隔的值传递到标志中来指定文件系统访问的特定路径。例如,以下命令允许对 /tmp/
文件夹进行写访问:
node --experimental-permission --allow-fs-write=/tmp/ --allow-fs-read=/home/index.js index.js
通配符模式也可以用于一次性允许访问多个文件或文件夹。例如,以下命令允许读取 /home/
目录中以 test
开头的所有文件和文件夹:
node --experimental-permission --allow-fs-read=/home/test* index.js
当启用权限模型时,process
对象的新 permission
属性可以用于在运行时检查是否已授予某个权限。
process.permission.has('fs.write'); // true
process.permission.has('fs.write', '/home/nodejs/protected-folder'); // true
需要注意,这些功能仍处于实验阶段,可能会在 Node.js 的未来版本中发生更改。
自定义 ESM loader hooks 接近稳定版
通过 loader 提供自定义 ES module 生命周期 hook(--experimental-loader=./foo.mjs
)现在在专用线程中运行,与主线程隔离开来。这为 loader 提供了单独的作用域,并确保 loader 和应用代码之间没有交叉污染。
为了与浏览器行为一致,import.meta.resolve()
现在返回同步操作;注意,用户 loader 中的resolve
hook 仍然可以是异步操作,如果 loader 作者希望的话,在应用代码中import.meta.resolve
仍将返回同步操作。
这些改变是标记 ESM loader 为稳定版前的最后几个未解决问题。一旦社区中没有重大错误报告一段时间,Node.js 团队就打算将 loader 标志、import.meta.resolve
和resolve
和load
hook 标记为稳定版。这使 ESM 的更广泛采用成为可能,因为重要的利益相关者将拥有一个稳定的 API 来构建分析和报告库。
V8 11.3
与往常一样,Node.js 中包含了V8引擎的新版本(更新到版本11.3,是 Chromium 113 的一部分),带来了改进的性能和新的语言特性,包括:
String.prototype.isWellFormed
和toWellFormed
;通过复制修改 Array 和 TypedArray 的方法; 可调整大小的 ArrayBuffer
和可增长的SharedArrayBuffer
;具有设置符号和字符串属性的 RegExp v 标志; WebAssembly 尾调用。
稳定版 Test Runner
Node.js 20 中包含了一个对 test_runner 模块的重要变更。该模块在最近的更新后被标记为稳定版。稳定版 Test Runner 包括编写和运行测试所需的基本组件,包括:
describe
、it/test
和 hooks 用于结构化测试文件mocking 观察模式 node --test
用于并行运行多个测试文件
以下是使用 Test Runner 的简单示例:
import { test, mock } from 'node:test';
import assert from 'node:assert';
import fs from 'node:fs';
mock.method(fs, 'readFile', async () => "Hello World");
test('synchronous passing test', async (t) => {
assert.strictEqual(await fs.readFile('a.txt'), "Hello World");
});
性能
随着新成立的 Node.js 性能团队的加入,自上一次主要发布以来,性能再次成为了一个重点。Node.js 20对运行时的基础部分(包括URL、fetch()
和EventTarget
)进行了许多改进。
初始化EventTarget
的成本减半,可以更快地访问使用它的所有子系统。此外,V8 Fast API 调用已被利用,以改进诸如URL.canParse()
和定时器等 API 的性能。
Node.js 20包括特定的变化,例如使用 C++ 编写的快速且符合规范的 URL 解析器 Ada 的更新版本2.0。
现在需要注入Blob来准备单个可执行文件
该项目在过去一年中一直致力于支持单个可执行文件(SEA),并最近实现了初步支持。由于该功能仍处于实验性阶段,团队将继续完善这一方法。在 Node.js 20 中,构建单个可执行文件现在需要从 JSON 配置中注入 Node.js 准备的 Blob,而不是注入原始的JS文件。
例如:sea-config.json
{
"main": "hello.js",
"output": "sea-prep.blob"
}
这会将 blob 写入 sea-prep.blob 文件:
node --experimental-sea-config sea-config.json
这个 Blob 现在可以注入到二进制文件中。这一改变是为了允许将多个共存资源嵌入到单个可执行文件(Single Executable Apps)中,从而开辟了新的用例。
Web Crypto API
Node.js 致力于与其他 JavaScript 环境的互操作性。例如,在 Node.js 20 中,Web Crypto API 函数的参数现在按照它们的 WebIDL 定义进行强制转换和验证,就像其他 Web Crypto API 实现一样。这进一步提高了与其他 Web Crypto API 实现的互操作性。
正式支持 ARM64 Windows
Node.js 具有广泛的平台和架构支持,Node.js 现在包括适用于 ARM64 Windows 的二进制文件,可以在该平台上进行本地执行。MSI、zip/7z包和可执行文件可以从 Node.js 下载站点以及所有其他平台上获得。CI 系统已更新,所有更改现在都在 ARM64 Windows 上进行了全面测试,以防止回归并确保兼容性。
Web Assembly System Interface(WASI)的进展
该项目继续在 Node.js 中实现WASI。值得注意的进展是,虽然它是实验性的,但不再需要命令行选项来启用 WASI,这应该使其更容易使用。WASI 团队期待着 preview2,并为未来做了一些更改。其中包括在调用new WASI()
时添加版本选项。在20.x版本中,版本是必需的,并且没有默认值。这对于支持新版本的应用非常重要,因为它们不会默认使用可能已过时的版本。然而,这也意味着任何依赖于版本默认值的代码都需要更新以请求特定版本。
注意事项
需要注意,Node.js 14 将在2023年4月停止维护,因此建议您开始计划升级到 Node.js 18(LTS)或Node.js 20(即将成为LTS)。
Node.js 16(LTS)将在2023年9月停止维护,这是为了与OpenSSL 1.1.1的支持结束时间一致,该时间将于2024年4月结束。
完整更新:https://nodejs.org/en/blog/release/v20.0.0 更新概述:https://nodejs.org/en/blog/announcements/v20-release-announce
往期推荐