source map generatorの使い方
source map rev.3の実装であるsource-mapを調べてみた。
このモジュールの提供するsource map generatorとしては、プリミティブなSourceMapGeneratorとより抽象化したSourceNodeが提供されている。
SourceMapGeneratorは、オリジナルと生成コードの対応関係を一つ一つ自分で追加してゆき、最終的にsource mapを生成する。
SourceNodeはコンパイラがJSを生成する際の中間表現として使うことを想定されており、オリジナルと生成コードの対応の計算をある程度自動的に行なってくれるようだ。
とりあえずSourceMapGeneratorを触ってみる。インターフェイスは極めて単純で、コンストラクタとaddMapping()とtoString()しかない。
#!/usr/bin/env NODE_PATH=lib node "use strict"; var sourceMap = require('source-map'); var Generator = sourceMap.SourceMapGenerator; var Consumer = sourceMap.SourceMapConsumer; // generate var gen = new Generator({ file: 'generated.js', sourceRoot: '/path/to/root' }); gen.addMapping({ source: 'original.js', original: { line: 1, column: 0 }, generated: { line: 2, column: 2 }, name: 'bar' // optional symbol name }); var map_json = gen.toString(); console.log("// mapping"); console.log(JSON.parse(map_json)); // consume (we don't need it directly) var consumer = new Consumer(map_json); var pos = consumer.originalPositionFor({ line: 2, column: 2 }); console.log("\n" + "// query"); console.log(pos);
結果:
// mapping { version: 3, file: 'generated.js', sources: [ 'original.js' ], names: [ 'bar' ], mappings: ';EAAAA', sourceRoot: '/path/to/root' } // query { source: '/path/to/root/original.js', line: 1, column: 0, name: 'bar' }
source-mapはrequirejsに依存していたりして少し使いづらいが、全体で1000行に満たないコードなので実装は難しくなさそうだ。Dartは一刻もはやくsouce mapに対応すべきだろう。