• Node.js v21.7.0 已发布 快来看下都有哪些新功能
  • 发布于 1个月前
  • 65 热度
    0 评论
2024年03月07日,Node.js v21.7.0 正式发布,带来了多项功能更新,亮点如下:

文本样式
在日常开发中,要在命令行展现个性化风格样式的文本,我们首先想到的是 chalk、colors、cli-color、kelur 等 NPM 包。近5年的下载趋势看,chalk 遥遥领先、遥遥领先、遥遥领先,更受开发者欢迎。

在 Node.js v21.7.0 版本,基于 util.inspect.colors 创建了一个新的 API 来格式化文本,使您可以用不同的颜色(如红色、蓝色...)和强调(斜体、粗体...)来格式化文本。
const { styleText } = require('node:util');

console.log(styleText('red', 'My red color message'));
console.log(styleText('green', 'My green color message'));
console.log(styleText('italic', 'My italic message'));
console.log(styleText('underline', styleText('italic', 'My italic underlined message'))); 
效果如下:

加载和解析环境变量
正常情况下,我们会很自然的会选用 dotenv 包来管理 env 变量。幸运的是,Node.js 21.7.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);
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');
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');
// 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);
crypto:实现了 crypto.hash() 方法
在之前版本中,计算hash,使用的都是 crypto.createHash(algorithm[, options]) 方法,尤其在生成 md5 时特别方便。此版本引入了一个辅助方法 crypto.hash(),可一次性计算输入内容的摘要。对于随时可用(非流式)的较小输入(<= 5MB),这比基于对象的 createHash() 快 1.2-2倍,而且由于不会创建中间对象,内存开销更少。
const crypto = require('node:crypto');
const name = 'FEDLAB';
// 堆代码 duidaima.com
// 方案一: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));
此外还有众多 bug 修复。
用户评论