続:vite-nodeで実行するTypeScriptのコードのスタックトレースの行を正しく表示したい
(Hackyな)解決編です。
これまでのあらすじ
vite-nodeで実行するTypeScriptのコードのスタックトレースの行を正しく表示したい
どうにかできないか調べた結果、既存の方法では無理そうというのがわかった
が、vite-node内部で持っているsourcemapをユーザコード側に渡すことができれば、できなくもない事が分かった
方針
vite-nodeのViteNodeRunnerを継承し、contextにファイルとsourcemapの対応データを入れるようにする
contextはユーザコードをラップした即時関数の引数として渡される
ユーザコード側でV8のStack trace APIを使ってスタックトレース出力に割り込む
vite-nodeで動かすことが前提なので他の環境は考えなくて良い
sourcemapを見てスタックトレースを書き換えて返す
at Constraint.execute (deltablue.js:525:2)
みたいなのをCallSiteから組み立てるのは大変なので、Errorオブジェクトのstack文字列の<file>:<line>:<column>をreplaceすることにする
vm.runInThisContextが使われているので、グローバルオブジェクトは呼び出し元とユーザコードとで共通
そのため、Error.prepareStackTraceは呼び出し元で書き換えれば、ユーザコード側でも反映される
最初この方法でやってダメだったのでコンテキストは別なんだと思い込んでいたが、別の部分が原因で動いてないだけだった様子
実装
できあがった物がこちら
https://github.com/elecdeer/vite-node-sourcemap-support
使い方はテストコードを見れば割と分かりそう
vite-nodeのProgramatic Usageみたいにrunnerを書いて、install(node)するだけ
こんな感じにsourcemapを反映したスタックトレースが取得できるようになります
Log4jsとかのスタックトレース出力についても、Errorオブジェクトから取得していれば反映される
code:before.ts
Error: Boom
at TestClass.boom (/Users/elecdeer/Dev/js/vite-node-sourcemap-support/test/testCode.ts:10:21)
at new TestClass (/Users/elecdeer/Dev/js/vite-node-sourcemap-support/test/testCode.ts:6:10)
at /Users/elecdeer/Dev/js/vite-node-sourcemap-support/test/testCode.ts:18:1
at async ViteNodeRunner.directRequest (file:///Users/elecdeer/Dev/js/vite-node-sourcemap-support/node_modules/vite-node/dist/client.mjs:217:5)
code: after.ts
Error: Boom
at TestClass.boom (/Users/elecdeer/Dev/js/vite-node-sourcemap-support/test/testCode.ts:18:20)
at new TestClass (/Users/elecdeer/Dev/js/vite-node-sourcemap-support/test/testCode.ts:7:9)
at /Users/elecdeer/Dev/js/vite-node-sourcemap-support/test/testCode.ts:33:0
at async SourcemapContextualizedRunner.directRequest (file:///Users/elecdeer/Dev/js/vite-node-sourcemap-support/node_modules/vite-node/dist/client.mjs:217:5)
まだnpmにはpublishしてないけど、そのうちする予定
今のままでも$ npm i git+https://github.com/elecdeer/vite-node-sourcemap-supportで一応インストールはできるはず
$ vite-nodeみたいにコマンドでサクッと実行できるようにもするかもしれない
所感
なんかできそうだったので勢いで実装してしまったけど、おとなしくrollupやらparcelを使ってsourcemap付きでビルドをした方がよさそう
このライブラリ自体はrollupでビルドしてるし...
あくまでワークアラウンドって感じなので、vite-nodeでサクッと動かしたいときに使うのに留めておいた方が良さげ
なんかうまいことできて、過程で色々知見を得られたのでぼくは満足です
#2022Aug