LoginSignup
9
4

More than 5 years have passed since last update.

err.stackに含まれるコードの位置情報をsource mapで元に戻す

Posted at

webpackやBabel、uglifyjsなどを使ってソースコードを変換している場合、err.stackに含まれるコードの位置に関する情報が変換後のコードの位置になっており、デバッグが難しい。err.stackに含まれる位置の情報をsource mapを使って、元のコードの位置に変換する方法をちょっとだけ調べた。

調べると色々なnpmパッケージが見つかるが、source-map-supportが有名っぽい。

# 検証用ディレクトリ作成
$ mkdir source-map-support-playground
$ cd source-map-support-playground

# 依存関係のインストール
$ yarn add babel-cli babel-preset-flow source-map-support -D

src.jsに無理やりFlowtypeのコードを書き、source-map-support/registerを読み込む。

// src.js
// @flow
require('source-map-support/register');

function throwsError(message: string) {
  throw new Error(`ERR: ${message}`);
}

throwsError('hoge');

Babelで変換し、変換後のファイルを実行してみる。

# source mapをつけて変換
$ babel --presets flow src.js --source-maps > lib.js

# 実行
$ node lib.js

/Users/xxxx/xxxx/src.js:5
  throw new Error(`ERR: ${message}`);
        ^
Error: ERR: hoge
    at throwsError (/Users/xxxx/xxxx/src.js:5:9)
    at Object.<anonymous> (/Users/xxxx/xxxx/src.js:8:1)
    at Module._compile (module.js:569:30)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:503:32)
    at tryModuleLoad (module.js:466:12)
    at Function.Module._load (module.js:458:3)
    at Function.Module.runMain (module.js:605:10)
    at startup (bootstrap_node.js:158:16)
    at bootstrap_node.js:575:3

変換後のlib.jsではなく、src.jsの位置で出力されていますね。


実装を見てみると、souce mapから元の位置を取得するのにmozillaのsource-mapを利用して、err.stackの書き換えはv8のStack Trace APIを使っているみたいです(Stack Trace APIについて、以前触れた記事があるので、よかったらどうぞ)。

今回はNode.jsで動かしましたが、Chromeでも動く(v8だから)ようです。Chrome以外ではerr.stackの書き換えはできなそうなので、mozillaのsource-mapを使ってerr.stack取得後に変換すればいけそうです。試していないので、負荷がどれくらいかかるかはわかりませんが。

Node.jsの場合だと、requireを書くだけなので、簡単でよいですね。

9
4
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
4