Node.js+CoffeeScript でソースマップを使ってデバッグを楽にする方法
以前、jQuery 1.9 のソースマップ対応で圧縮版でもデバッグが簡単になった話 を書いたけど、Node.js でソースマップする方法を紹介する。
何がうれしいかというと、Node.js で CoffeeScript や TypeScript、JSX なんかを使ったときに、例外に含まれるスタックトレースに変換前の位置を表示できる。
やり方は簡単。source-map-support というモジュールを require()
するだけ。
ためしに使ってみた
GitHub に動かし方が書いてあるので、その通りにやってみる。
こんな感じの demo.coffee
があったとする。
require 'source-map-support'
foo = ->
bar = -> throw new Error 'this is a demo'
bar()
foo()
npm install source-map-support
で source-map-support モジュールをインストールしておく。
生の CoffeeScript がソースマップに対応してないので、CoffeeScriptRedux を使って JavaScript に変換する。
$ CoffeeScriptRedux/bin/coffee --js -i demo.coffee > demo.js
$ echo '//@ sourceMappingURL=demo.js.map' >> demo.js
$ CoffeeScriptRedux/bin/coffee --source-map -i demo.coffee > demo.js.map
あとは普通に実行すれば、スタックトレースには coffee ファイルの位置が出てくる。
$ node demo.js
demo.coffee:4
bar = -> throw new Error 'this is a demo'
^
Error: this is a demo
at bar (demo.coffee:4:19)
at foo (demo.coffee:5:3)
at Object.<anonymous> (demo.coffee:6:3)
at Object.<anonymous> (demo.coffee:6:6)
at Module._compile (module.js:449:26)
:
bar (demo.coffee:4:19)
のところにご注目。
本当だったら、ここがコンパイル後の demo.js 上の位置になってるはずなんだけど、source-map-support モジュールのおかげで、コンパイル前の位置が表示されている。
ここでは示してないけど、Error
を catch
したときの error.stack
も coffee ファイルの場所になる。
CoffeeScript だけじゃなく、TypeScript や JSX もソースマップには対応しているし、圧縮やファイル結合したきにもソースマップさえ吐いておけば、このように変換前の位置情報を出力してくれるようになるので、便利便利である。
仕組み
動作原理が気になったので source-map-support.js のソースをざっと読んでみた。
一番の肝は Error.prepareStackTrace()
を定義して、スタックトレースを書き換えているところ。どうやら V8 エンジンの Stack Trace API というものがあるようだ。
また、未処理の例外のときに例外が発生した位置のソースを表示するために、process.on('uncaughtException', ...)
でがんばって処理している。
ソースマップの解析には Mozilla の source-map モジュール を使っているようだ。
まとめ
Node.js でもソースマップが使えるよ。
(参考記事) Node.js Source Map Support for Better Compiled JavaScript Debugging - Badass JavaScript