通译自:6 major features of node.js 19. details of node.js 19 new features… | by jennifer fu | oct, 2022 | better programming
node.js 14 将在 2023 年 4 月结束更新维护,node.js 16 (lts) 预计将在 2023 年 9 月结束更新维护。
而node 19 在 2022-10-18 发布。【相关教程推荐:nodejs视频教程】
我们知道 node.js 版本分两种:lts 和 current
其中,current 版本通常每 6 个月发布一次。
每年 4 月份发布新的偶数版本;
每年 10 月份发布新的奇数版本;
在刚过去的 10 月,发布的 v19.0.1 成为最新的 “current” 尝鲜版,它一共带来 6 大特性。
1. http(s)/1.1 keepalive 默认为 truenode.js v19 设置 keepalive 默认值为 true,这意味着所有出站的 http(s) 连接都将使用 http 1.1 keepalive,默认时间为 5s;
代码测试:
const http = require('node:http');console.log(http.globalagent);const https = require('node:https');console.log(https.globalagent);
我们可以对比看看 v16 和 v19 的 node server agent 配置差异:
v16% nvm use 16now using node v16.0.0 (npm v7.10.0)% node serveragent { _events: [object: null prototype] { free: [function (anonymous)], newlistener: [function: maybeenablekeylog] }, _eventscount: 2, _maxlisteners: undefined, defaultport: 80, protocol: 'http:', options: [object: null prototype] { path: null }, requests: [object: null prototype] {}, sockets: [object: null prototype] {}, freesockets: [object: null prototype] {}, keepalivemsecs: 1000, keepalive : false, maxsockets: infinity, maxfreesockets: 256, scheduling: 'lifo', maxtotalsockets: infinity, totalsocketcount: 0, [symbol(kcapture)]: false}agent { _events: [object: null prototype] { free: [function (anonymous)], newlistener: [function: maybeenablekeylog] }, _eventscount: 2, _maxlisteners: undefined, defaultport: 443, protocol: 'https:', options: [object: null prototype] { path: null }, requests: [object: null prototype] {}, sockets: [object: null prototype] {}, freesockets: [object: null prototype] {}, keepalivemsecs: 1000, keepalive: false, maxsockets: infinity, maxfreesockets: 256, scheduling: 'lifo', maxtotalsockets: infinity, totalsocketcount: 0, maxcachedsessions: 100, _sessioncache: { map: {}, list: [] }, [symbol(kcapture)]: false}
第 18、40 行,keepalive 默认设置为 false;
v19% nvm use 19now using node v19.0.0 (npm v8.19.2)% node serveragent { _events: [object: null prototype] { free: [function (anonymous)], newlistener: [function: maybeenablekeylog] }, _eventscount: 2, _maxlisteners: undefined, defaultport: 80, protocol: 'http:', options: [object: null prototype] { keepalive: true, scheduling: 'lifo', timeout: 5000, nodelay: true, path: null }, requests: [object: null prototype] {}, sockets: [object: null prototype] {}, freesockets: [object: null prototype] {}, keepalivemsecs: 1000, keepalive: true, maxsockets: infinity, maxfreesockets: 256, scheduling: 'lifo', maxtotalsockets: infinity, totalsocketcount: 0, [symbol(kcapture)]: false}agent { _events: [object: null prototype] { free: [function (anonymous)], newlistener: [function: maybeenablekeylog] }, _eventscount: 2, _maxlisteners: undefined, defaultport: 443, protocol: 'https:', options: [object: null prototype] { keepalive: true, scheduling: 'lifo', timeout: 5000, nodelay: true, path: null }, requests: [object: null prototype] {}, sockets: [object: null prototype] {}, freesockets: [object: null prototype] {}, keepalivemsecs: 1000, keepalive: true, maxsockets: infinity, maxfreesockets: 256, scheduling: 'lifo', maxtotalsockets: infinity, totalsocketcount: 0, maxcachedsessions: 100, _sessioncache: { map: {}, list: [] }, [symbol(kcapture)]: false}
第 14、16、42、44 行设置 keepalive 默认值及时间;
启用 keepalive 能使连接重用,提高网络的吞吐量。
另外,服务器将在调用 close() 自动断开空闲的客户端,内部依靠 http(s).server.close api 实现;
这些修改,进一步优化了体验和性能。
2. 稳定的 webcrypto apiwebcrypto api 是一个使用密码学构建的系统接口,在 node.js v19 趋于稳定(除 ed25519、ed448、x25519、x448 外)。
我们可以通过调用 globalthis.crypto 或 require('node:crypto').webcrypto 来访问,下面以 subtle 加密函数为例;
const { subtle } = globalthis.crypto;(async function() { const key = await subtle.generatekey({ name: 'hmac', hash: 'sha-256', length: 256 }, true, ['sign', 'verify']); console.log('key =', key); const enc = new textencoder(); const message = enc.encode('i love cupcakes'); console.log('message =', message); const digest = await subtle.sign({ name: 'hmac' }, key, message); console.log('digest =', digest);})();
首先生成 hmac 密钥,生成的密钥可同时用于验证消息数据完整性和真实性;
然后,对字符串 i love cupcakes 加密;
最后创建 消息摘要,它是一种加密散列函数;
在控制台显示:key 、message 、digest 信息
% node serverkey = cryptokey { type: 'secret', extractable: true, algorithm: { name: 'hmac', length: 256, hash: [object] }, usages: [ 'sign', 'verify' ]}message = uint8array(15) [ 73, 32, 108, 111, 118, 101, 32, 99, 117, 112, 99, 97, 107, 101, 115]digest = arraybuffer { [uint8contents]: <30 01 7a 5c d9 e2 82 55 6b 55 90 4f 1d de 36 d7 89 dd fb fb 1a 9e a0 cc 5d d8 49 13 38 2f d1 bc>, bytelength: 32}
3. 自定义 esm resolution 调整node.js 已经删除 --experimental-specifier-resolution ,其功能现在可以通过自定义加载器实现。
可以在这个库中测试:nodejs/loaders-test: examples demonstrating the node.js ecmascript modules loaders api
git clone https://github.com/nodejs/loaders-test.git% cd loaders-test/commonjs-extension-resolution-loader% yarn install
比如 loaders-test/commonjs-extension-resolution-loader/test/basic-fixtures/index.js 文件:
import { version } from 'process';import { valueinfile } from './file';import { valueinfolderindex } from './folder';console.log(valueinfile);console.log(valueinfolderindex);
./file 如果没有自定义加载器,不会去查找文件的扩展名,比如 ./file.js 或 ./file.mjs
设置自定义加载器后,则可解决上述问题:
import { isbuiltin } from 'node:module';import { dirname } from 'node:path';import { cwd } from 'node:process';import { fileurltopath, pathtofileurl } from 'node:url';import { promisify } from 'node:util';import resolvecallback from 'resolve/async.js';const resolveasync = promisify(resolvecallback);const baseurl = pathtofileurl(cwd() + '/').href;export async function resolve(specifier, context, next) { const { parenturl = baseurl } = context; if (isbuiltin(specifier)) { return next(specifier, context); } // `resolveasync` works with paths, not urls if (specifier.startswith('file://')) { specifier = fileurltopath(specifier); } const parentpath = fileurltopath(parenturl); let url; try { const resolution = await resolveasync(specifier, { basedir: dirname(parentpath), // for whatever reason, --experimental-specifier-resolution=node doesn't search for .mjs extensions // but it does search for index.mjs files within directories extensions: ['.js', '.json', '.node', '.mjs'], }); url = pathtofileurl(resolution).href; } catch (error) { if (error.code === 'module_not_found') { // match node's error code error.code = 'err_module_not_found'; } throw error; } return next(url, context);}
测试命令:
% node --loader=./loader.js test/basic-fixtures/index (node:56149) experimentalwarning: custom esm loaders is an experimental feature. this feature could change at any time(use `node --trace-warnings ...` to show where the warning was created)hello from file.js
将不会再报错,正常运行。
4. 移除对 dtrace/systemtap/etw 支持在 node.js v19中,移除了对 dtrace/systemtap/etw 的支持,主要是因为资源的优先级问题。
数据表明很少人用到 dtrace、systemtap 或 etw,维护它们没有多大的意义。
如果你想恢复使用,可提 issues => github.com/nodejs/node…
5. 升级 v8 引擎至 10.7node.js v19 将 v8 javascript 引擎更新至 v8 10.7,其中包含一个新函数 intl.numberformat,用于格式化敏感数字。
intl.numberformat(locales, options)
对于不同的语言,传入不同的 locales:
const number = 123456.789;console.log(new intl.numberformat('de-de', { style: 'currency', currency: 'eur' }).format(number));console.log(new intl.numberformat('ja-jp', { style: 'currency', currency: 'jpy' }).format(number));console.log(new intl.numberformat('ar-sa', { style: 'currency', currency: 'egp' }).format(number));console.log(new intl.numberformat('zh-cn', { style: 'currency', currency: 'cny' }).format(number));
6. 试验 node watch 模式运行时增加了 node --watch 选项。
在 "watch" 模式下运行,当导入的文件被改变时,会重新启动进程。
比如:
const express = require("express");const path = require("path");const app = express();app.use(express.static(path.join(__dirname, "../build")));app.listen(8080, () => console.log("express server is running on localhost:8080"));
% node --watch server(node:67643) experimentalwarning: watch mode is an experimental feature. this feature could change at any time(use `node --trace-warnings ...` to show where the warning was created)express server is running on localhost:8080
node.js 14 将在 2023 年 4 月结束更新维护,node.js 16 (lts) 预计将在 2023 年 9 月结束更新维护。
建议大家开始计划将版本按需升级到 node.js 16(lts)或 node.js 18(lts)。
更多node相关知识,请访问:nodejs 教程!
以上就是node.js 19正式发布,聊聊它的 6 大特性!的详细内容。