◆ test モジュールや parseArgs 関数が Stable になった
◆ loader が別スレッドで実行されてグローバル変数を共有できなくなった
◆ その他色々

気づけば Node.js も 20 まで来たんですね

stable

Test runner モジュールparseArgs 関数 が Stable になりました

これらは便利なものなので Stable になったなら安心して使っていけますね

resolve

ブラウザに合わせて import.meta.resolve が同期関数になりました
これまで非同期だったのですね
でも import.meta.resolve に await した覚えないけど と思ったら Node.js ではまだフラグ必須のものでした
--experimental-import-meta-resolve フラグを指定した覚えがないので たぶん Node.js だと一度も使ったことなくて気づいてなかったみたいです

import.meta.resolve は loader を使ったときの resolve 関数に相当するものです
つまり resolve 関数の中では非同期処理を行えます
resolve 関数で 3 秒待ってから結果を返すようにしてみます

[loader.js]
export const resolve = async (specifier, context, nextResolve) => {
if (specifier === "module1") {
await new Promise(r => setTimeout(r, 3000))
return { shortCircuit: true, url: "http://localhost/module1" }
}

return nextResolve(specifier)
}

[index.js]
console.time("resolve")
const resolved = import.meta.resolve("module1")
console.timeEnd("resolve")
console.log({ resolved })

[root@f6977c800aa5 /]# node --experimental-loader ./loader.js --experimental-import-meta-resolve index.js
(node:121) ExperimentalWarning: Custom ESM Loaders is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
resolve: 3.006s
{ resolved: 'http://localhost/module1' }

同期的に 3 秒待つことになってます

loader

loader では個人的に残念な変更が起きました
先週カスタムローダーでモジュールをモックするという記事を書いたばかりですが さっそくこれが使えなくなりました

ローダーを設定できる部分は変わらないのですが メインのスクリプト側とローダーが別スレッドに分けられました
モジュールの解決方法をメインスレッドから指示したいのでグローバル変数を通してローダーに関数を渡していたのですがこれができなくなりました

[loader.js]
export const resolve = async (specifier, context, nextResolve) => {
console.log(globalThis.value)
return nextResolve(specifier)
}

[index.js]
globalThis.value = "changed"
import("fs")

こういうコードを用意しても 表示されるのは undefined です
index.js でセットした変数は loader.js で参照できません

ファイルに書き込むなど方法はありますが イマイチな方法になります

SEA

18.16 で追加された Single Executable Application という Node.js アプリケーションを単体の実行ファイル化する機能があります
まだ experimental ですし 手順を見ると npx で外部の postject というパッケージを実行する必要があります
その他機能のように安定してきた頃に Node.js 本体に組み込まれるのでしょう

この SEA を作る手順が 20 で少し変わって --experimental-sea-config オプションに構成ファイルを指定して blob を作る必要があるようです
https://nodejs.org/dist/latest-v20.x/docs/api/single-executable-applications.html#single-executable-applications

使い所はありそうですが 現状だと手順が面倒ですし わざわざ使わなそうです
単体ファイルにする必要がないところでやっても ソースコードを見たり編集したりが簡単にできなくなって スクリプト言語の良さが減りますし

エントリポイントのファイルだけ指定したらあとは全部自動でやってくれるくらいになったらいいのですけどね

今の手順を見る感じだと Node.js 実行ファイルをコピーしてそれを指定する必要があります
それに埋め込みを行うパッケージ名は postject です
Node.js バイナリの末尾にソースコードをまとめた blob をくっつける みたいな動作なんでしょうか

V8

V8 バージョンは 11.3 になるようです
つまり Chrome 113 相当ですね

最近の toSorted や isWellFormed などが使えます



LTS 化はいつもどおり秋のはずなので それまでにまだ機能は追加されるはずですが 最近は構文の追加など劇的な変化はなさそうですね