Node.js 21 来了!

2023-10-24 09:53:47 浏览数 (1)

2023-10-17 Node.js 迎来了一个新的重大版本更新 Node.js 21。相信有同学已经感概这版本升级也太快了,我还在用 Node.js 10 结果 21 都应来了...

Node.js 21 主要包含以下几点:

  • JavaScript 引擎 V8 已升级至 11.8
  • 稳定的 WebStreams,有助于在浏览器应用程序中以小尺寸处理数据
  • 一个新的实验性标志用于切换模块默认值。
  • 对测试运行器的许多更新,允许用户运行功能测试并导出结果
  • ...更多内容参见下面正文

需要注意的是 Node.js 20 还处入 “当前” 版本,不过按计划是在 2023-10-24 发布 LTS 版本,到时 Node.js 21 将取代 Node.js 20 成为我们的“当前”发布线。根据发布计划,Node.js 21将在接下来的6个月内成为“当前”版本,直到 2024 年 4 月。

以下为当前的 Release 时间表

该项目在许多领域取得了进展,许多新功能和修复已经流入现有的 LTS 版本。因此,Node.js 21 的变更仅代表自上一次重大发布以来的一小部分功能和工作。

JavaScript 引擎 V8 已升级至 11.8

通常 V8 的更新会为 Node.js 带来一些性能提升和新的语言特性,包括:

数组分组:

代码语言:javascript复制
const array = [1, 2, 3, 4, 5];

// `Object.groupBy` groups items by arbitrary key.
// In this case, we're grouping by even/odd keys
Object.groupBy(array, (num, index) => {
  return num % 2 === 0 ? 'even': 'odd';
});
// =>  { odd: [1, 3, 5], even: [2, 4] }

参考 https://github.com/tc39/proposal-array-grouping

ArrayBuffer.prototype.transfer,参考 https://github.com/tc39/proposal-arraybuffer-transfer

WebAssembly extended-const expressions,参考 https://github.com/WebAssembly/extended-const

Node.js test 运行器支持通配符

在最新的 Node.js 更新版本中,测试运行器在指定 --test 参数时引入了通配符表达式的支持。这意味着您现在可以使用强大的通配符模式更高效、更灵活地运行测试。例如,您可以使用类似 node --test **/*.test.js 的命令来执行多个目录中所有具有 .test.js 扩展名的文件的测试。

ESM: --experimental-default-type 标志切换模块默认值

新的标志 --experimental-default-type 可用于切换 Node.js 使用的默认模块系统。已经明确定义为 ES 模块CommonJS 的输入,例如通过 package.json"type" 字段或 .mjs/.cjs 文件扩展名或 --input-type 标志,不受影响。目前被隐式视为 CommonJS 的将在 --experimental-default-type=module 下被解释为 ES 模块:

  • 通过 --evalSTDIN 提供的字符串输入,如果 --input-type 未指定。
  • .js 结尾或没有扩展名的文件,如果同一文件夹或任何父文件夹中没有 package.json 文件。
  • .js 结尾或没有扩展名的文件,如果最近的父 package.json 字段缺少 type 字段;除非该文件夹位于 node_modules 文件夹内。
  • 此外,如果传递了 --experimental-wasm-modules,则无扩展名的文件将被解释为 WebAssembly,并且文件以 WebAssembly前言asm 开头。

我们还在探索使用检测 ES 模块语法作为 Node.js 知道何时解释文件为 ES 模块的方法。我们的目标是最终找到一种支持 ES 模块语法的默认方式,而不引入太多破坏性变更。

由 Jacob Smith 在 #49144 中贡献。参考 https://github.com/nodejs/node/pull/49869

为 fs.writeFile 函数添加 flush 选项

在写入文件时,数据可能不会立即刷新到永久存储。这允许后续的读取操作看到过时的数据。这个 PRfs.writeFile 函数系列中添加了一个 'flush' 选项,它在成功的写入操作结束时强制刷新数据。

由 Colin Ihrig 在 #50009 中贡献。参考 https://github.com/nodejs/node/pull/50009

性能

性能是运行时的一个重要属性,我们的 @nodejs/performance 团队在过去一年中一直在努力改进 URL、fetch、streams、node:fs 和 HTTP

Node.js 流团队继续优化可写流和可读流。在这个版本中,流维护者 Robert Nagy 带领团队通过删除多余的检查、利用位图以及以更有效的方式安排回调来进一步优化流。

由 Robert Nagy 在 #50012 中贡献。参考 https://github.com/nodejs/node/pull/50012

HTTP

以前,在写入分块响应时,无论响应是否被 "封住",Node.js 都会为每次调用 .write(...) 创建一个单独的块。这导致了客户端和服务器端都不必要的开销。

这个改变通过在取消 "封住" 响应时创建一个单个块来解决这个问题。

考虑以下基于 ?Transfer-Encoding 文档的示例:

代码语言:javascript复制
res.cork();
res.write('Mozilla');
res.write(' Developer Network');
res.uncork();

在每个块的开头,您需要添加当前块的长度以十六进制格式,后跟 'rn',然后是块本身,再后跟另一个 'rn'。终结块是一个常规块,唯一的例外是它的长度为零。

结果是一个响应流:

代码语言:javascript复制
HTTP/1.1 200 OK
Content-Type: text/plain
Transfer-Encoding: chunked
7rn
Mozillarn
18rn
 Developer Networkrn
0rn
rn

在这个 PR 之后,取消 "封住" 响应时,所有内容都合并到一个单个块中,避免了许多不必要的开销。

代码语言:javascript复制
HTTP/1.1 200 OK
Content-Type: text/plain
Transfer-Encoding: chunked
25rn
Mozilla Developer Networkrn
0rn
rn

由 Robert Nagy 在 #50167 中贡献。参考 https://github.com/nodejs/node/pull/50167

llhttp 9.1.2 严格模式强制执行

在以前的 Node.js 版本中,默认情况下未启用严格模式。通过最新的更新,以前包括在严格模式中的所有设置现在都已默认启用,增强了代码的可靠性和安全性。

头部之后必须存在 rn(以前只允许r)。此外,块之后必须存在 rn,以确保数据处理的一致性。

解析 Connection: close 头部之后不再允许数据传输。这个改变增强了协议的遵循性,并改善了连接处理。

为了适应特定用例,--insecure-http-parser 标志存在。此选项允许用户禁用前述更改,并与以前的解析行为保持向后兼容性。

这些更新旨在增强系统的整体稳定性,并提高 Node.js 应用程序中数据处理的一致性。鼓励开发人员检查其代码库并相应地调整其实现,以确保与最新版本无缝集成。

navigator 对象集成

Node.js 21 中,我们引入了全局 navigator 对象,增强了 Web 互操作性。现在,开发人员可以通过 navigator.hardwareConcurrency 访问硬件并发信息。

Yagiz Nizipli#47769 中贡献。参考 https://github.com/nodejs/node/pull/47769

弃用

  • [4b08c4c047] - (SEMVER-MAJOR) lib: runtime deprecate punycode(Yagiz Nizipli) #47202
  • [ccca547e28] - (SEMVER-MAJOR) util: runtime deprecate promisify-ing a function returning a Promise(Antoine du Hamel) #49609

行动起来

尝试使用新的 Node.js 21 版本!我们很高兴听取您的反馈意见。通过使用 Node.js 21 测试您的应用程序和模块,有助于确保您的项目与最新的 Node.js 变更和功能的未来兼容性。

还需要注意的是,Node.js 16(LTS) 已经终止生命周期,因此我们强烈建议您开始计划升级到 Node.js 18(LTS)Node.js 20(LTS)

本文翻译自 Node.js Blog:https://nodejs.org/en/blog/announcements/v21-release-announce

如果想了解更多 Node.js 版本信息,可参考笔者之前写的 Node.js 版本介绍。

Node.js 版本知多少?又该如何选择?

0 人点赞