source-mapの正当性についての検討
あるsource-mapが、本当にソースコードの各行に対応したマッピングを行えているかどうかを評価したい。
背景
light-ts-loaderというwebpackのloaderを作っていて、このloaderを使ったときに吐き出されるsource-mapが自分のloaderのせいで壊れていないかを保証したかった
問題
何を以って "正しいsource-mapである" とするかの判定が難しい。 たいていsource-mapが壊れているとわかるのは、Webブラウザの開発者ツールで開いて、ブレークポイントを打って、リロードしても見当違いの部分でデバッガが動いたときだ。 この時、 "見当違いの部分で" というのは完全に人間の判断によるものなので、機械的に評価するためにはなんらかの基準を与える必要がある。
計画
今回のloaderはTypeScriptからJavaScriptへの変換なので、TypeScriptのバージョンさえ固定されていれば入力に対して出力は冪等であることが利用できる。 変換のパスは TypeScript(module.ts) -> JavaScript(module.js) -> JavaScript(bundle.js) の2段階なので、source-mapを利用して最初のTypeScriptのあるポジションに対応するbundle.jsのポジションを取得し、そのポジションのコードが最初のTypeScriptコードのトランスパイル後コードと一致すればいい。
つまり、次の module.ts
の return { str };
と bundle.js
の return {str: str};
を結ぶsource-mapであれば "正しい" と言えそうだ。
module.ts
export function wrap(str: string) { return { str }; }
bundle.js
// .... function wrap(str) { return { str: str }; } exports.wrap = wrap; // ....
実施
愚直に書いてうまくいった。理論上はコード断片のハードコードなしにTypeScriptのAPIを使ってトランスパイル前後のコードを照合できる気がするが、そこまでする気力はなかった。
https://github.com/laco0416/light-ts-loader/blob/master/test/test-source-map.ts
反省
もっと汎用的に書きたい。暇があったら頑張る。