Node.js 19版本于2022年10月18号发布,Node.js 19将是发布当日到未来6个月的“Current”版本,直到2023年4月,Node.js 18在10月晚些时候进入长期支持期(LTS),你可以在Node v19.0.0 (Current) Notable Changes查看完整更新说明。
Node.js 19主要更新了以下特性,可以在官方下载体验Node.js 19,本文也将轻度体验此版本:
node --watch
(实验特性)- HTTP KeepAlive默认开启
- 稳定的Web Crypto API
- V8引擎更新
此文使用nvm下载和管理Node.js版本。
查看可用版本:
$ nvm list available
| CURRENT | LTS | OLD STABLE | OLD UNSTABLE |
|--------------|--------------|--------------|--------------|
| 19.1.0 | 18.12.1 | 0.12.18 | 0.11.16 |
| 19.0.1 | 18.12.0 | 0.12.17 | 0.11.15 |
| 19.0.0 | 16.18.1 | 0.12.16 | 0.11.14 |
| 18.11.0 | 16.18.0 | 0.12.15 | 0.11.13 |
| 18.10.0 | 16.17.1 | 0.12.14 | 0.11.12 |
| 18.9.1 | 16.17.0 | 0.12.13 | 0.11.11 |
| 18.9.0 | 16.16.0 | 0.12.12 | 0.11.10 |
| 18.8.0 | 16.15.1 | 0.12.11 | 0.11.9 |
| 18.7.0 | 16.15.0 | 0.12.10 | 0.11.8 |
| 18.6.0 | 16.14.2 | 0.12.9 | 0.11.7 |
| 18.5.0 | 16.14.1 | 0.12.8 | 0.11.6 |
| 18.4.0 | 16.14.0 | 0.12.7 | 0.11.5 |
| 18.3.0 | 16.13.2 | 0.12.6 | 0.11.4 |
| 18.2.0 | 16.13.1 | 0.12.5 | 0.11.3 |
| 18.1.0 | 16.13.0 | 0.12.4 | 0.11.2 |
| 18.0.0 | 14.21.1 | 0.12.3 | 0.11.1 |
| 17.9.1 | 14.21.0 | 0.12.2 | 0.11.0 |
| 17.9.0 | 14.20.1 | 0.12.1 | 0.9.12 |
| 17.8.0 | 14.20.0 | 0.12.0 | 0.9.11 |
| 17.7.2 | 14.19.3 | 0.10.48 | 0.9.10 |
安装Node 19:
$ nvm install 19.1.0
Downloading node.js version 19.1.0 (64-bit)...
Extracting node and npm...
Complete
npm v8.19.3 installed successfully.
切换到node 19:
$ nvm use 19
Now using node v19.1.0 (64-bit)
$ node -v
v19.1.0
安装就绪,我们试试它的新特性。
node --watch
(实验特性)
这是一个很实用,也是很多人盼望了许久的比较实用的特性,但目前仍处于实验阶段。用过webpack的同学对这个--watch
参数应该很眼熟,用于监听到文件变化执行编译。Node 19引入此特性也是为了在主文件和引入的文件发生改变时,重启进程。
为了验证它,我准备了如下目录结构:
// index.js
require('./deep1')
console.log('主文件运行...')
// deep1/index.js
require('./deep2')
console.log('第一层级文件运行...')
// deep1/deep2/index.js
console.log('第二层级文件运行...')
在不带--watch
的情况下运行时这样
$ node index
第二层级文件运行...
第一层级文件运行...
主文件运行...
在--watch
下运行会有一个警告(告诉你注意下这是一个实验中的特性,可能随时会变):
$ node --watch index
(node:44952) 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)
第二层级文件运行...
第一层级文件运行...
主文件运行...
Completed running 'index'
我们将三个文件改了文件内容如下并分别保存:
require('./deep1')
console.log('主文件更新更新更新运行...')
会分别发生三次重启,最后一次的结果:
Restarting 'index'
第二层级更新更新更新文件运行...
第一层级文件更新更新更新运行...
主文件更新更新更新运行...
Completed running 'index
检验结果是ok的,watch
模式将可以让开发者更专注地关注代码,而不是运行终端。
HTTP KeepAlive默认开启
KeepAlive是HTTP1.1为了复用连接,提供更好的吞吐量而生的。HTTP1.1标准早已将KeepAlive设置为默认开启,Node 19对其进行了支持,默认情况下保持连接的时间为5秒,即Keep-Alive: timeout=5
,另外,Node.js HTTP服务器会在调用close()时自动断开空闲的启用HTTP Keep-Alive的客户端连接。
我们来建一个Node HTTP服务来验证它:
// index.js
const http = require("http");
const listener = function (req, res) {
res.writeHead(200);
res.end("Hello, Node.js 19!");
};
const server = http.createServer(listener);
server.listen(9527);
运行这个文件:
node index.js
接着我们访问刚建立的HTTP服务器localhost:9527
:
可以看到响应头返回了KeepAlive相关的两个字段:
- Connection: keep-alive
- Keep-Alive: timeout=5
稳定的Web Crypto API
Node从16版本开始对W3C
的提出的Web Cryptography API进行支持,到Node.js 19开始你可以安心的使用相关的Node API(除Ed25519、Ed448、X25519和X448算法外是稳定的), 也就是Web Crypto API。
这意味着你可能不再需要一些第三方库来进行加密(针对部分算法来说),SubtleCrypto
类可用于生成对称(秘密)密钥或非对称密钥对(公钥和私钥),SubtleCrypto
将在下面的示例中演示,我们写一个例子来验证它的加解密过程。
// 其中subtle是就是上面说的SubtleCrypto实例
const { subtle, randomBytes } = require("node:crypto");
async function main () {
// 初始向量
const iv = randomBytes(16);
const key = await subtle.generateKey(
{
name: "AES-CBC",
hash: "SHA-256",
length: 256,
},
true,
["encrypt", "decrypt"]
);
const secretMessage = "Hello, Node.js 19!";
// 加密
const encrypted = await subtle.encrypt(
{
name: "AES-CBC",
iv: iv,
},
key,
secretMessage
);
// 解密
const decrypted = await subtle.decrypt(
{
name: "AES-CBC",
iv: iv,
},
key,
encrypted
);
const dec = new TextDecoder("utf-8");
console.log(`解密字符:${dec.decode(decrypted)}`);
}
main()
运行下这个文件:
$ node index.js
解密字符:Hello, Node.js 19!
V8引擎更新
V8引擎更新到10.7版本,这是Chromium 107的一部分。这个版本包含了JavaScript API的一个新特性: Intl.NumberFormat
,这个API也很实用,它可以根据语言对数据进行格式化,下面我们来试试。
const number = 31415926.58;
const china = new Intl.NumberFormat("zh-CN", {
style: "currency",
currency: "CNY",
});
console.log(china.format(number));
const us = new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
});
console.log(us.format(number));
const eu = new Intl.NumberFormat("de-DE", {
style: "currency",
currency: "EUR",
});
console.log(eu.format(number));
运行结果:
¥31,415,926.58
$31,415,926.58
31.415.926,58 €
此外,它还可以本地化数字:
const number = 31415926.58;
// 中文
console.log(new Intl.NumberFormat('zh-Hans-CN-u-nu-hanidec').format(number));
输出:
三一,四一五,九二六.五八
它甚至可以给数字加上单位,其中unit
参数所有值参考这里,复合单位用-per-
连接:
const number = 31415926.58;
// 部分支持中文单位
console.log(new Intl.NumberFormat('zh-CN', {
style: 'unit',
unit: 'kilobit-per-year'
}).format(50));
console.log(new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'kilobit-per-year'
}).format(50));
console.log(new Intl.NumberFormat('zh-CN', {
style: 'unit',
unit: 'liter',
unitDisplay: 'short' // "short" | "long" | "narrow"
}).format(50));
输出:
50 kb/年
50 kb/y
50升
Node v19.1.0
在2022-11-14发布了node v19.1.0,这是目前最新的Node版本。此版本主要在测试运行器(Test runner),增加mock.method
方法用于在现有对象方法上创建模拟:
import test from 'node:test';
import assert from 'node:assert';
test('spies on an object method', (t) => {
const number = {
value: 5,
add(a) {
return this.value + a;
},
};
t.mock.method(number, 'add');
assert.strictEqual(number.add(3), 8);
assert.strictEqual(number.add.mock.calls.length, 1);
});
$ node index.mjs
TAP version 13
# Subtest: spies on an object method
ok 1 - spies on an object method
---
duration_ms: 2.3918
...
1..1
# tests 1
# pass 1
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 12.0682
另外Node 19.1.0增加了fs.watch
方法在Linux平台上的递归支持,即recursive: true
参数:
const watcher = fs.watch(testDirectory, { recursive: true });
watcher.on('change', function(event, filename) { });
其他
- Node 19附带了llhttp
- npm 附带版本更新为8.19.2
- Node.js 14将在2023年4月结束维护,Node.js 16 (LTS)将在2023年9月结束维护