ts-node の代わりに esbuild-register を使ってスピードアップ

commits1 min read読了の目安(約1700字

ts-node では実行時に型チェックをしてくれますが、 esbuild では型チェックそのものをスキップします。型の整合性などは別途 npx tsc --noEmit や IDE などで担保してください

参考
https://twitter.com/mryhryki/status/1383574194764488707

Node.js で TypeScript をトランスパイルしながら実行できる、 esbuild-register というパッケージがあります。

https://github.com/egoist/esbuild-register

非常に速い esbuild を使いながら雑に TypeScript が実行できちゃう頼もしいパッケージです。

今までのメインプレイヤーであった ts-node よりも非常に速いです。次の小さなスクリプトでも 2.5 倍程度の速度が出ています。

function wait(duration: number) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {resolve(true)}, duration)
  })
}

async function main({duration}: {duration: number}) {
  await wait(duration)
  console.log('finished')
}

main({
  duration: 0
})

3 回実行した結果の平均を取ったものが次になります。 CPU 時間以外の単位は秒です。

tool user system cpu total
esbuild-register 0.393 0.160 88.3% 0.624
ts-node 1.937 0.233 137.7% 1.575

お手元で試したい場合は clone すれば試せるものを用意したので esbuild の速さを体感してみてください。

ts-node を使っているプロジェクトでは切り替えると如実に効率が上がると思いますので、ぜひ切り替えてみてください。

esbuild-register の仕組み

伝えたいことは以上ですべてですが、 esbuild-register がどのように動くかという点を書いておきます。

esbuild-register を用いてスクリプトを実行する場合、次のコマンドを叩きます。

node --require esbuild-register /path/to/your/script.ts

Node.js の --require オプションを使っていますね。これは雑に説明すると、指定したモジュールを読み込んでから本筋のスクリプトを実行するためのものです。

esbuild-register はこれを用いて esbuild によるトランスパイル処理を仕込んでいるのですね。

Mocha によるテスト実行時によく使ったオプションですが、見なくなって久しいので最近の方向けに説明を書いてみました。