• Node.js v20.12.0 正式发布 快来看下有哪些新特性
  • 发布于 1个月前
  • 54 热度
    0 评论
  • 且醉
  • 0 粉丝 31 篇博客
  •   
2024年03月26日,Node.js v20.12.0(LTS)版本正式发布。

下面来看看该版本带来的主要更新:
1.crypto:实现了 crypto.hash() 方法
在之前版本中,计算hash,使用的都是 crypto.createHash(algorithm[, options]) 方法,尤其在生成 md5 时特别方便。此版本引入了一个辅助方法 crypto.hash(),可一次性计算输入内容的摘要。对于随时可用(非流式)的较小输入(<= 5MB),这比基于对象的 createHash() 快 1.2-2倍,而且由于不会创建中间对象,内存开销更少。

另外,在 Node.js v21.7.0 版本中也介绍了该特性更新。
const crypto = require('node:crypto');
const name = 'FEDLAB';

// 方案一:crypto.createHash
const hash = crypto.createHash('md5');
hash.update(name);
// 69382e924f0e37978b8cf2d292f7617b
console.log(hash.digest('hex'));

// 方案二:crypto.hash()
// 69382e924f0e37978b8cf2d292f7617b
console.log(crypto.hash('md5', name));
2.加载和解析环境变量
正常情况下,我们会很自然的会选用 dotenv 包来管理 env 变量。

Node.js 20.12.0 版本提供了 process.loadEnvFile(path) 和 util.parseEnv(content) 两个 API 来处理环境变量:
process.loadEnvFile(path):使用该函数可以加载指定 path 下的 .env 文件。如果未指定路径,则会自动加载当前目录下的 .env 文件。
util.parseEnv(content):使用该函数可以解析指定的环境变量内容。现在支持 .env 文件中的多行值。
.env 文件:
MULTI_LINE="HELLO
WORLD"
代码示例:
process.loadEnvFile('./.env');

/*
打印
{
  ...,
  MULTI_LINE: 'HELLO\nWORLD'
}
*/
console.log(process.env);
3.新的连接尝试事件
net.createConnection 中新增了三个事件:
connectionAttempt:当尝试建立新连接时触发。在 Happy Eyeballs 的情况下,可能会发生多次。
connectionAttemptFailed:连接尝试失败时发出。如果是 Happy Eyeballs,可能会多次触发。
connectionAttemptTimeout:连接尝试超时:连接尝试超时时发出。在 Happy Eyeballs 的情况下,最后一次尝试将不会发出此信息。如果不使用 Happy Eyeballs,则根本不会发出此警报。
此外,还修正了以前的一个错误,即在前一次连接失败后,在连接被用户破坏后,可能会开始新的连接尝试。这将导致断言失败。

4.权限模型变更
Node.js 20.12.0 对实验性权限模型进行了多项修复,并新增了两项半重要提交。我们添加了一个新标志 --allow-addons 以在使用权限模型时启用附加组件。
node --experimental-permission --allow-addons
5.sea: 支持嵌入资源
现在,用户可以通过在配置中添加键路径字典作为 assets 字段来包含资源。在构建时,Node.js 会从指定路径读取资源并将其捆绑到准备 blob 中。在生成的可执行文件中,用户可以使用 sea.getAsset() 和 sea.getAssetAsBlob() API 检索资源。
{
  "main": "/path/to/bundled/script.js",
  "output": "/path/to/write/the/generated/blob.blob",
  "assets": {
    "a.jpg": "/path/to/a.jpg",
    "b.txt": "/path/to/b.txt"
  }
}
单一可执行应用程序可通过以下方式访问资源:
const { getAsset } = require('node:sea');
// Returns a copy of the data in an ArrayBuffer
const image = getAsset('a.jpg');
// Returns a string decoded from the asset as UTF8.
const text = getAsset('b.txt', 'utf8');
// Returns a Blob containing the asset without copying.
const blob = getAssetAsBlob('a.jpg');
6.vm: 支持使用默认 loader 处理动态导入
此版本添加了对使用 vm.constants.USE_MAIN_CONTEXT_DEFAULT_LOADER 作为 importModuleDynamically 选项的支持,适用于除 vm.SourceTextModule 之外的所有 vm API。这样,如果用户不需要自定义加载过程,就可以使用快捷方式在编译代码中支持动态 import(),而不会丢失编译缓存。当默认加载器通过此选项而非 --experimental-vm-modules 实际处理 import() 时,我们会发出实验警告。
const { Script, constants } = require('node:vm');
const { resolve } = require('node:path');
const { writeFileSync } = require('node:fs');
// 堆代码 duidaima.com
// Write test.js and test.txt to the directory where the current script
// being run is located.
writeFileSync(
  resolve(__dirname, 'test.mjs'),
  'export const filename = "./test.json";'
);
writeFileSync(resolve(__dirname, 'test.json'), '{"hello": "world"}');
// Compile a script that loads test.mjs and then test.json
// as if the script is placed in the same directory.
const script = new Script(
  `(async function() {
    const { filename } = await import('./test.mjs');
    return import(filename, { with: { type: 'json' } })
  })();`,
  {
    filename: resolve(__dirname, 'test-with-default.js'),
    importModuleDynamically: constants.USE_MAIN_CONTEXT_DEFAULT_LOADER,
  }
);
// { default: { hello: 'world' } }
script.runInThisContext().then(console.log);
除了以上主要特性更新外,Node.js v20.12.0 版本还进行了其他部分特性更新及问题修复。
用户评论