Node.js v17 來了,看看都有哪些新功能?
Node.js v17 版本已發布,取代了 v16 做為當前版本,新的 v17 版本提供了一些新功能:基于 Promise 的其它核心模塊 API、錯誤堆棧尾部增加 Node.js 版本信息、OpenSSL 3.0 支持、v8 JavaScript 引擎更新至 9.5。
基于 Promise 的 API
Node.js 項目的一項持續性戰略計劃是為 Node.js 核心模塊提供基于 Promise 的 API 支持,近年來已為 timer、stream 模塊提供了 Promise API 支持。
Node.js v17 版本為 readline 模塊提供了基于 Promise 的 API 支持。該模塊提供了一個接口用于從一個可讀流對象逐行讀取數據。
結合 process.stdin 可讀取用戶在終端輸入的數據。如下例所示:
- // test.mjs
- import * as readline from "node:readline/promises";
- import { stdin as input, stdout as output } from 'process';
- const rl = readline.createInterface({ input, output });
- const answer = await rl.question('“Nodejs技術棧” 的域名是什么:');
- console.log(`答案: ${answer}`);
- rl.close();
運行之后,效果如下所示:
readline 模塊的更多信息參考 readline_readline。
錯誤堆棧增加 Node.js 版本
堆棧跟蹤是診斷應用程序錯誤信息的重要組成部分,在 Node.js v17 版本中,如果因為一些致命的錯誤導致進程退出,在錯誤堆棧的尾部將包含 Node.js 的版本信息。
如果想忽略該信息,運行時在命令行指定 --no-extra-info-on-fatal-exception 標志。
OpenSSL 3.0 支持
Node.js v17 版本包含了近期發布的 OpenSSL 3.0,根據 OpenSSL 的發布策略,OpenSSL 1.1.1 將在 2023-09-11 結束支持,這個日期也在 Node.js v18 LTS 結束日期之前。
因為 OpenSSL 3.0 對允許的算法和密鑰大小增加了嚴格的限制,預計會對生態系統造成一些影響,在 Node.js v17 版本包含 OpenSSL 3.0 以便在下一個 LTS 版本之前為用戶的測試和反饋留出時間。
例如,md4 這是 OpenSSL 3.0 默認不再允許的一個算法,如果是在 Node.js 17 之前的 Node 版本中,應用程序是可以正常運行的,但在 Node.js v17 中將拋出一個 error code 為 ERR_OSSL_EVP_UNSUPPORTED 的錯誤信息。
- import crypto from 'crypto';
- console.log(crypto.createHash('md4').update('123', 'utf8').digest('hex'))
Node.js v17 版本下運行之后得到如下錯誤信息。
一個臨時的解決方法是運行時增加 --openssl-legacy-provider 標志,應用程序不在報錯。
- $ node --openssl-legacy-provider test.mjs
- c58cda49f00748a3bc0fcfa511d516cb
V8 更新至 9.5
v8 在 8.1 版本開啟了 Intl.DisplayNames API,支持語言、區域、貨幣、腳本四種類型,現在添加了兩種新的類型:calendar、dateTimeField,分別返回不同的日歷類型和日期時間字段的顯示名稱。對于國際化應用很有幫助。
- const esCalendarNames = new Intl.DisplayNames(['zh'], { type: 'calendar' });
- console.log(esCalendarNames.of('roc')); // 民國紀年
- const enCalendarNames = new Intl.DisplayNames(['en'], { type: 'calendar' });
- console.log(enCalendarNames.of('roc')); // Minguo Calendar
日期時間字段國際化名稱展示。
- function printDate(dateTimeField) {
- console.log(
- `${dateTimeField.of('year')} ${dateTimeField.of('month')} ${dateTimeField.of('day')}`
- );
- }
- printDate(new Intl.DisplayNames(['zh'], { type: 'dateTimeField' })) // 年 月 日
- printDate(new Intl.DisplayNames(['en'], { type: 'dateTimeField' })) // year month day
- printDate(new Intl.DisplayNames(['KOR'], { type: 'dateTimeField' })) // 년 월 일
- printDate(new Intl.DisplayNames(['THA'], { type: 'dateTimeField' })) // ปี เดือน วัน
Intl.DateTimeFormat API 在 v8 9.5 版本中為 timeZoneName 選項新增加了四個值:shortGeneric、longGeneric、shortOffset、longOffset。
通過以下代碼示例可看到之間的區別。
- console.log(new Intl.DateTimeFormat('zh').format(new Date())); // 2021/01/01
- console.log(new Intl.DateTimeFormat('zh', { timeZoneName: 'shortGeneric' }).format(new Date())); // 2021/01/01 中國時間
- console.log(new Intl.DateTimeFormat('zh', { timeZoneName: 'longGeneric' }).format(new Date())); // 2021/01/01 中國標準時間
- console.log(new Intl.DateTimeFormat('zh', { timeZoneName: 'shortOffset' }).format(new Date())); // 2021/01/01 GMT+8
- console.log(new Intl.DateTimeFormat('zh', { timeZoneName: 'longOffset' }).format(new Date())); // 2021/01/01 GMT+08:00
參見 v8 9.5 release 文檔 閱讀更多信息。
其它信息
按照 Node.js 發布時間表,Node.js v12 將于 2022 年 4 月結束生命周期。Node.js v16 在 2021 年 10 月 26 升級為 LTS,即長期支持版本。
Node.js 的奇數版本不是穩定的版本(例如,當前的 Node.js v17 ),它的生命周期很短,不要用于生產環境。
對 Node.js 版本信息不了的、不知道如何安裝 Node.js 的參考文章 “Node.js 版本知多少?又該如何選擇?”。
Reference
https://medium.com/the-node-js-collection/node-js-17-is-here-8dba1e14e382
https://nodejs.org/en/blog/release/v17.0.0/