ソースマップの新しい形式のコメント //# と対応ブラウザ

SassなどのCSSプリプロセッサを使ったり、JavaScriptファイルをminimize化する際に困るのがデバッグですが、最近はソースマップに対応したブラウザも登場して開発がやりやすくなっています。

ソースマップを利用する際はファイル末尾に特定形式のコメントを挿入するか、HTTPヘッダを送信してソースマップファイルの場所を指定しますが、ブラウザによって対応度に差があったり、最近になってコメントのフォーマットに新バージョンが登場したり動向が激しいため、調べてみました。

ソースマップを使ってみる

JavaScript の圧縮ライブラリ UglifyJS(github.com) を使った例を紹介します。なお、UglifyJS自体のインストール方法は省略します。

まずは元となるJavaScriptファイル(hoge.js)を用意します。

(function() {
"use strict";
  var foo = 100;
  var bar = foo * 2;
  console.log("bar: " + bar);
})();

これを uglifyjs コマンドで圧縮します。その際、--source-mapオプションを指定してソースマップファイルも吐き出すようにします。

uglifyjs hoge.js -o hoge.min.js --source-map hoge.js.map

すると hoge.min.js と hoge.js.map が出力され、 hoge.min.js の末尾にはソースマップファイルのありかを示すコメントが挿入されます。

!function(){"use strict";var foo=100;var bar=foo*2;console.log("bar: "+bar)}();
//# sourceMappingURL=hoge.js.map

この hoge.min.js を読み込んだHTMLファイルをソースマップに対応したブラウザで表示すると、開発ツールから元ファイル(hoge.js)を表示することができます。

オリジナル画像
図1Google Chrome 30(Canary)のDevToolsを表示したところ

コメント形式

先ほどの例では //# から始まるコメントが挿入されましたが、少し古いバージョンだと //@ を使ったこんな形式となっていました。

/*
//@ sourceMappingURL=hoge.js.map
*/

ところが、これはIEの条件コンパイル(msdn.microsoft.com)と競合してしまいます。例えばこんなJavaScriptの場合。

/*@cc_on @*/
var sourceMappingURL = "foo";
//@ sourceMappingURL=1;hoge.js.map

IEでは変数 sourceMappingURL の値が上書きされ、 1 になってしまいます。それを防ぐため、UglifyJSの古いバージョンでは前後を /* */ で囲んでいたのだと思いますが、ともあれ今後は //# を使った方が良いでしょう。

対応ブラウザ

新しいコメント形式はつい最近に定義されたため[1]、まだ正式版で対応しているブラウザはありません。

Firefoxは来週6日にリリース予定のバージョン23でソースマップに対応しますが、この時点では旧方式のコメントにしか対応しないようです。現在、Auroraチャンネル(24.0a2)では新コメントも認識するので、正式版で利用できるまでにはもう少しかかりそうですね。Google Chrome と Opera も次のメジャーアップデートを待つ必要がありそうです。

ブラウザ現行バージョンソースマップ対応新コメント対応
Firefox2223(Beta)24(Aurora)
Google Chrome28対応済み29(Beta)
Opera15対応済み16(Next)

HTTPヘッダでの指定

ファイル末尾にコメントを挿入するやり方を見てきましたが、SourceMap ヘッダで指定することもできます。

minimize化したJSファイルが hoge.min.js 、ソースマップファイルが hoge.js.map というファイル名な場合、Apacheだと httpd.conf や .htaccess にこんな指定をすることでヘッダーを送出できます。

SetEnvIf Request_URI ([^/]+).min.js$ MAP=$1.js.map
Header set SourceMap %{MAP}e env=MAP
Header set X-SourceMap %{MAP}e env=MAP

現状はまだ X-接頭辞が必要なので、合わせて X-SourceMap ヘッダも吐いています。これはそのうち不要になるでしょう。

ブラウザ現行バージョンX-SourceMapヘッダ対応SourceMapヘッダ対応
Firefox22未対応未対応
Google Chrome28対応済み29(Beta)
Opera15対応済み16(Next)

ただしこれはあくまでJavaScriptの例で、他のフォーマットは状況が異なります。たとえばSassの場合は、Chrome Beta や Opera Next はX-接頭辞付きも含めてHTTPヘッダには対応しておらず、対応が確認できたのは Chrome Canary (30) のみです。