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
模块:
- 通过
--eval
或STDIN
提供的字符串输入,如果--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 选项
在写入文件时,数据可能不会立即刷新到永久存储。这允许后续的读取操作看到过时的数据。这个 PR
在 fs.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
之后,取消 "封住"
响应时,所有内容都合并到一个单个块中,避免了许多不必要的开销。
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 版本知多少?又该如何选择?