Node.jsのv12がLTSになり、v13がcurrentとしてリリースされました。 ダウンロードは公式ページから行えます。
今回はNode.js v13の主な変更点を紹介したいと思います。
以下リリースノートにあるNotable Changesからいくつかピックアップします。
assert (PR: #28263)
assert.throws()またはassert.reject()でthrowされたエラーの検証にコンストラクターが使われた場合、throwされたエラーの代わりにAssertionErrorがスローされます。
コードで見た方がいいかもしれません。
| // v12 | |
| const assert = require('assert'); | |
| const SomeError = class extends Error{}; | |
| try { | |
| // 第一引数でthrowされたエラーがSomeErrorか判定 | |
| assert.throws(() => {throw new TypeError({})}, SomeError) | |
| } catch (e) { | |
| // eはTypeError | |
| assert.ok(e instanceof TypeError) | |
| } |
| // v13 | |
| const assert = require('assert'); | |
| const SomeError = class extends Error{}; | |
| try { | |
| // 第一引数でthrowされたエラーがSomeErrorか判定 | |
| () => assert.throws(() => {throw new TypeError({})}, SomeError) | |
| } catch (e) { | |
| // eはTypeErrorではなくAssertionErrorに内包されている | |
| assert.strictEqual( | |
| e, | |
| { | |
| generatedMessage: true, | |
| actual: new TypeError({}), | |
| expected: AssertionError, | |
| code: 'ERR_ASSERTION', | |
| name: 'AssertionError', | |
| operator: 'throws', | |
| message: 'The error is expected to be an instance of "AssertionError". ' + | |
| 'Received "TypeError"\n\nError message:\n\n[object Object]' | |
| } | |
| ) | |
| } |
build (PR: #29887)
full-icuでビルドされるようになり、i18n系の機能ですべての言語をサポートしました。
Node.jsはこれまでビルド後のバイナリサイズの増加への懸念により、--with-intl=small-icuオプションを付けてビルドしていたバイナリを配布していました。
しかし、v13からは--with-intl=full-icuでビルドしたバイナリを配布するようになりました。
懸念されていたバイナリのサイズですが、macOSだと35MBから49MBになります。
オプションによる言語サポートの違いは以下の表のとおりです。こちらからも確認できます。
挙動の違いに関するサンプルコードは以下のとおりです。
| const january = new Date(9e8); | |
| const spanish = new Intl.DateTimeFormat('es', { month: 'long' }); | |
| console.log(spanish.format(january)) | |
| // 'M01' v12 | |
| // 'enero` v13 |
v12以下(small-icuでビルドされたバージョン)はM01と出力しますが、v13以降(full-icuでビルドされたバージョン)はeneroと出力します。
console (PR: #29251)
console.timeEnd()とconsole.timeLog()の結果がミリ秒ではなく時分秒の単位で出力するようになりました。
単位はh(時)、min(分)、s(秒)があります。
サンプルコードは以下の通りです。
| const label = 'test'; | |
| console.time(label); | |
| setTimeout(() => { | |
| console.timeEnd(label); | |
| }, 3000); | |
| // 3001.732ms v12 | |
| // 3.001s v13 |
v12では3001.732msと出力されていましたが、v13からは3.001sと出力されます。
deps (PR: #29694)
JavaScriptエンジンのV8のバージョンが7.8になりました。
これによりObjectの分割代入のパフォーマンス、メモリ使用量、WASMの起動時間が改善されます。
詳しくはV8のブログを読んでください。
http (PR: #29589)
古いHTTPパーサーが削除されました。
v12からすでにデフォルトではllhttpが使われています。
しかし、--http-parser=legacyとオプションをつけてnodeを起動すると古いパーサーを使うことも可能でした。
v13からはEnd-of-Lifeとなりました。オプション自体が削除されました。
llhttpはTypeScriptで書かれたhttpパーサーです。
古いHTTPパーサーは保守が難しく、またアーキテクチャ上パフォーマンスに問題がありました。
llhttpは保守性向上のためにTypeScriptで書かれています。それをCのコードやビットコードに変換しています。
古いHTTPパーサーに比べてパフォーマンスはかなり向上しています。
http, http2 (PR: #27558)
デフォルトのサーバータイムアウト時間が変わりました。
これまでサーバーのタイムアウトの時間はデフォルト2分でした。
リクエストが完了するまでに2分以上かかる場合、ソケットは閉じられ空のレスポンスを返していました。
そのため、画像の変換やサイズが大きいファイルのアップロードなど処理に時間がかかる場合、処理の途中でリクエストが閉じられることがありました。
これまでも--http-server-default-timeout=millisecondsオプションを使うことでユーザー側でもこの時間を変更することは可能でした。0に設定することでサーバータイムアウトを無効にすることもできました。
v13からはデフォルトで0が設定されるようになりました。つまりサーバータイムアウトが無効になりました。
最後に
今回紹介したのは一部の機能になります。自分が気になった変更をまとめただけですので、他にもすごい変更点はあるかもしれません。
また、ES Modulesもv13からフラグなしで使えるようになっていく予定になっています。
New Release Plan · Issue #400 · nodejs/modules · GitHub
PullRequestはもう出ていてマージされるとフラグ無しで使えるようになるので、興味のある方はウォッチすると良いかと思います。
Node.js v13は2020年6月でEnd-of-Lifeになる予定です。
次のNode.js v14は例年通りだと2020年4月にリリースされ10月末にLTSになる予定です。今回紹介したv13の機能も含まれます。