Skip to content

Instantly share code, notes, and snippets.

@twada
Last active August 29, 2015 14:05
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save twada/103d34a3237cecd463a6 to your computer and use it in GitHub Desktop.
Save twada/103d34a3237cecd463a6 to your computer and use it in GitHub Desktop.
power-assert 多段 SourceMap 対応の方針

power-assert 多段 SourceMap 対応の方針

試験は twada/battlefield-sourcemaps で行っている

power-assert 出力行の補正

  • SourceMap 対応が入った espower 0.9.0 を使う
  • espower(ast, options) の第二引数 options に sourceMap というキーで上流の SourceMap オブジェクトを入れる
  • options.sourceMap が与えられた場合、 AST 変換時のファイル名、ファイル行番号を補正する
  • AST の段階でできるのはここまで

各 instrumentor 対応方針

基本方針

  • 方針が安定するまで SourceMap 対応の espower 0.9.0 を直接使う (espower-source ではなく)
  • 上流の SourceMap を探す (探し方は各 instrumentor によって異なる)
  • 上流 SourceMap を発見した場合 espower の options に入れる
  • escodegen から出てきた SourceMap を上流の SourceMap とつなぐ
  • 下流に流す (流し方は各 instrumentor によって異なる)

grunt-espower

作業 PR support multistage sourcemap by vvakame · Pull Request #2 · twada/grunt-espower -> リリース完了

grunt では上流 SourceMap がどう来るか調べる必要がある。

  • js と同一ディレクトリに外部 .map ファイルのパターン
  • js ファイル末尾に base64 コメントで付いているパターン

gulp-espower

espower-loader

  • しくみとして下流は存在しないので、読み込んだファイルに base64 形式の SourceMap が付いていた場合 espower に渡すだけで良い?

espowerify

  • 作業 PR SourceMap transform chain by twada · Pull Request #4 · twada/espowerify -> リリース完了
  • 参考: browserify v2 adds source maps
  • browserify の多段 SourceMap は各 transform がファイル末尾コメントの SourceMap に base64 で埋め込む責務を担う
  • stream から読み込んだコード末尾に上流の SourceMap が付いている可能性がある
  • 上流 SourceMap が付いていた場合は espower が出した SourceMap とつないでからコメントにして末尾に付ける

espower-coffee

  • CoffeeScript コンパイラから出てきた SourceMap を espower に渡す
@vvakame
Copy link

vvakame commented Aug 25, 2014

@twada twada/battlefield-sourcemaps#1 TypeScriptのテストケースを追加してみましたがこれで正しいのかわかりません…(キリ
gulp-tscが hoge.ts をコンパイルした時の処理のstreamに hoge.js じゃなくて hoge.js.map も突っ込んでくるみたいなファンキーなことをしていて現状だとgulp-espowerが死にそうです…。

@twada
Copy link
Author

twada commented Aug 25, 2014

gist のコメント、通知が来ないので気づきませんでした……ありがとうございます! その後の gulp-tsc への要望挙げもすばらしいです。

@vvakame
Copy link

vvakame commented Aug 26, 2014

上記対応だと、ソースの位置がずれるとかありそうでした。
例えば以下のようなケース。

test
└─fixture
  └─hoge.coffee

を、以下のように変換

test
└─fixture
  └─hoge.coffee
tmp
└─hoge.js

tmp/hoge.jsをブラウザ上から参照すると以下のように復元される

tmp
├──test
│   └── fixture
│      └── hoge.coffee
└─hoge.js

これの対応が必要です
https://github.com/twada/grunt-espower/blob/0d74379916edc3ebc0ebda2cb733e3d8aabed763/tasks/espower.js#L59
ざっくりと以下の手順

  1. 最初のファイルが変換された時の作業ディレクトリを調べる(入力のsourceRootやsourcesの起点)
  2. 最終出力先を調べる (espowerのdest)
  3. 新しいsourceRootを決める 最終出力先と1の作業ディレクトリとの相対パス
  4. 新しいsourcesを決める 最初の元ソースを3にあわせてパスの補正をする 新しいsourceRootからの相対パス
inWorkingDir test/fixtures
outTo /Users/vvakame/Dropbox/work/grunt-espower/tmp/coffee_mocha_node.js
sourceRoot ../test/fixtures
inSources step1. file 1 /Users/vvakame/Dropbox/work/grunt-espower/test/fixtures/coffee_mocha_node.coffee
inSources step2. file 1 coffee_mocha_node.coffee

これで全てのパターンがカバーできてるかはこれから調べないといけなさそうです。

@twada
Copy link
Author

twada commented Aug 26, 2014

ありがとうございます。なるほど…… sources と sourceRoot の管理は頭が痛いですね……

browserify では SourceMap の中は絶対パスにしていて、変換の最後に thlorenz/mold-source-map を使って全てのパスを相対パスに変換しています。このような作業を他の環境でも行わなければならないということですね……

現状の戦略を調べたところでは、

  • browserify は変換チェーン内では全て絶対パスで扱い、最後にまとめて相対パスにする
  • gulp-sourcemaps は変換チェーン内で全て相対パスで扱ってほしいと書いてある (が、それを守っていない plugin もある…)

というような感じです。

Grunt もパスの扱いに何らかの指針があれば、それに則っていくのが良さそうですね。
現時点のパス補正路線は悪くないと思います。 altJS 大手の変換が破綻無くできるようなら、同路線で行けそうですね。

@vvakame
Copy link

vvakame commented Aug 26, 2014

gruntの方針よくわからなかったです…。
mold-source-mapのDependsにgrunt系がいなかったのでなさそうかな…?という雑な結論になりました。

複数TypeScript(tscにconcatさせる)も試してみました。
出てくるSourceMapのデータを見るとうまく処理できていそうなんですが、ブラウザ上で試してみると3つconcatしているのに1つしか出なかったり(assertを使う+grunt-espowerの場合)、TypeScript上でブレークポイント打っても止まらなかったり(assertを使わない+grunt-espowerの場合)してます…。

@twada
Copy link
Author

twada commented Aug 26, 2014

concat 系、動きが怪しいものが多そうかな、という気がしています。

browserify だけはブレークポイントも含めてきちんと動作していますが、 gulp-concat は組み合わせ方によってはデバッガにファイルが一つしか出なかったりしています。

ブレークポイントは複数打ってみてください。ブレークポイントひとつだけだと、上手く行かない場合もありそうです (ここは要検証)。

concat 系がきちんと動く条件ですが、 sources の配列と soucesContents の配列の添字が一致していて、変換チェーンの一番最初のファイル名とファイル内容になっていること、そして各変換段階がきちんと前のファイルとつないでいることが条件かなと推測しています。

@vvakame
Copy link

vvakame commented Aug 26, 2014

https://github.com/sokra/source-map-visualization/
concat時の対応関係をこれでみたいけどこれが対応してなくて辛さがありますね…。

@vvakame
Copy link

vvakame commented Aug 26, 2014

http://safx-dev.blogspot.jp/2013/08/javascriptsource-map.html
JavaScriptのSource Mapの内部表現について

@vvakame
Copy link

vvakame commented Aug 26, 2014

ながながと書いた文が消えて悲しみを背負った…。
生成されたmappingsを頑張って読むとsources[0]しか参照されてない気がするのでSourceMapつなぐところがイケてないのでは…??という気がしてきました。concatしないとsources[0]しか参照しなくても問題ないので顕在化しないとかそういう感じかなぁ…と。

@twada
Copy link
Author

twada commented Aug 26, 2014

生成されたmappingsを頑張って読むとsources[0]しか参照されてない気がするのでSourceMapつなぐところがイケてないのでは…??という気がしてきました。concatしないとsources[0]しか参照しなくても問題ないので顕在化しないとかそういう感じかなぁ…と。

むむ、それですね……!

@vvakame
Copy link

vvakame commented Aug 26, 2014

たぶんなおった!!!!!!!
azu/multi-stage-sourcemap#1 手元をこの通りに書き換えて動かすとなんかウゴっぽい気がします。

@twada
Copy link
Author

twada commented Aug 26, 2014

たぶんなおった!!!!!!!

Great!!!!

@vvakame
Copy link

vvakame commented Aug 26, 2014

@twada sourceRoot が file:// のパターンとか http:// のパターンって動作確認してますか??(テスト用生成コードが簡単に手に入るなら欲しいマンです

@twada
Copy link
Author

twada commented Aug 26, 2014

SourceMap 生成元が file や http プロトコルを付けるのをあまり見かけなくて、いまいちピンと来ていない状態です。このため現時点ではテスト用の状況も作成できてない感じです……

@vvakame
Copy link

vvakame commented Aug 26, 2014

fileプロトコルはTypeScriptで--mapRootに不正なパラメータとか指定すると生成される気がします。
httpはインターネッツのSourceMap解説の例で見かけるような気が…。
実用上たぶん問題にならない気もしますが、grunt-espowerのパス補正のコードがそれらに対応してないのでgruntユーザの手元で発火する可能性があるかもしれません(被害報告がきたら君gruntでやってるよね?って聞くパターンということで…

@twada
Copy link
Author

twada commented Aug 26, 2014

そうですね。 file / http プロトコルは対応すべき状況が発生したら改めて考えるくらいで良いかな、と思っています。

@vvakame
Copy link

vvakame commented Aug 27, 2014

https://twitter.com/azu_re/statuses/504429825516244992
microsoft/TypeScript#496
えっあっ file:// が出てくるのってバグだったの…??? ってなってるなどしてます(まだよくわからない

@twada
Copy link
Author

twada commented Aug 27, 2014

おおお、 file:// が出るのは TypeScript コンパイラのバグの可能性があるのですか……

@twada
Copy link
Author

twada commented Sep 6, 2014

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment