一、简介
4月18日,Node正式发布20版本,亮点有Node.js权限模型、同步import.meta.resolve、稳定的test_runner、V8 JavaScript引擎更新到11.3、Ada更新到2.0等等
下载地址(自行百度)
注意:Node.js 20将于10月进入长期支持(LTS),但在此之前,它将是未来六个月的“Current”版本。鼓励探索此最新版本提供的新功能和好处,并评估它们的应用程序的潜在影响。
二、亮点更新
Permission Model(权限模板)
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的能力将受到限制。
随着--allow-fs read和--allow-fs-write标志的引入,使用Node.js的开发人员现在可以更好地控制文件系统访问。这些实验特性允许对Node.js进程可以访问文件系统的哪些部分进行更精细的控制。
启用这些标志,开发人员可以使用--experimental -permission标志以及所需的权限。例如,运行以下命令可以对整个文件系统进行读写访问:
node --experimental-permission --allow-fs-read=* --allow-fs-write=* index.js
还可以通过向标志传递逗号分隔的值来指定文件系统访问的特定路径。例如,以下命令允许对/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
启用“权限模型”后,可以使用 permission 对象的新process属性来检查是否在运行时授予了特定权限。
process.permission.has('fs.write'); // true process.permission.has('fs.write', '/home/nodejs/protected-folder'); // true
需要注意的是,这些功能仍然是实验性的,可能会在Node.js的未来版本中发生变化
Custom ESM loader hooks nearing stable(自定义ESM装载机挂钩接近稳定)
通过 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的方法
- 可调整大小的ArratBuffer和可增长的SharedArrayBuffer
- 带有设置符号和字符串属性的RegExp v标志
- WebAssembly尾部调用
Stable Test Runner(稳定的Test Runner)
Node.js版本20的最新更新包括对test_runner模块的一个重要更改。在最近的更新之后,该模块已被标记为稳定。稳定的测试运行程序包括用于编写和运行测试的构建块,包括:
- describe、it/test和 hooks 用于结构化测试文件
- mocking
- watch模式
- node --test用于并行运行多个测试文件
测试运行程序还包括一些尚未稳定的部分,包括报告程序和代码覆盖。
这是一个使用测试运行程序的简单示例:
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) => { // This test passes because it does not throw an exception. assert.strictEqual(await fs.readFile('a.txt'), "Hello World"); });
Performance(性能)
随着新成立的Node.js性能团队,自上一次Major发布以来,人们重新关注性能。Node.js 20包括对运行时基本部分的许多改进,包括URL、fetch()和EventTarget。
初始化EventTarget的成本降低了一半,从而可以更快地访问使用它的所有子系统。此外,V8快速API调用还被用来提高URL.canParse()和计时器等API的性能。
Node.js 20包括一些特定的更改,例如Ada的更新版本2.0,这是一个用C++编写的快速且符合规范的URL解析器。
展望提高性能的新方法,目前正在努力通过重构来降低符合规范的成本,以摆脱对流、URL、URLSearchParams和字符串解码器的品牌验证检查。这有助于支持我们的总体目标,即在有意义的地方遵守规范。
Preparing single executable apps now requires injecting a Blob(需要注入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注入二进制文件中。做出这一改变是为了允许将多个共存资源嵌入SEA(单一可执行应用程序),从而打开新的用例。
Web Crypto API(Web加密API)
该项目致力于与其他JavaScript环境的互操作性。作为Node.js 20中的一个例子,与其他Web Crypto API实现一样,Web CryptoAPI函数的参数现在根据其WebIDL定义进行强制和验证。这进一步提高了与Web Crypto API的其他实现的互操作性。
Official support for ARM64 Windows(支持ARM64 Windows)
Node.js有广泛的平台和架构支持,人们似乎希望它能在任何地方运行。我们很高兴与大家分享Node.js现在包含了ARM64 Windows的二进制文件,允许在平台上进行本机执行。MSI、zip/7z软件包和可执行文件可从Node.js下载网站以及所有其他平台获得。CI系统已经更新,所有更改现在都在ARM64 Windows上进行了全面测试,以防止倒退并确保兼容性。
Progress on Web Assembly System Interface (WASI)
该项目继续在Node.js中实现WASI。一些值得注意的进展是,它是实验性的,但不再需要命令行选项来启用WASI。这应该会让它更容易消费。由于从事WASI工作的团队期待着预览2,因此还进行了一些更改以规划未来。这包括在调用new WASI()时添加一个版本选项。在20.x版本中,该版本是必需的,并且没有默认值。这一点很重要,因为支持新版本,所以应用程序不会默认为可能过时的版本。然而,这确实意味着,任何依赖于版本默认值的代码都需要更新以请求特定版本。
Call to action
需要注意的是,Node.js 14将于2023年4月停止使用,因此我们建议您开始计划升级到Node.js 18(LTS)或Node.js 20(即将升级为LTS)。
考虑Node.js 16(LTS)将于2023年9月停止使用,这是从2024年4月提前的,以配合OpenSSL 1.1.1的支持结束。