WebStorm+Chrome+BrowserSyncでJavaScriptデバッグ


「WebStorm」とJetBrains製品共通のChromeプラグイン「JetBrains IDE Support」を利用すると、ブラウザ上で実行されるJavaScriptでも、本格的なデバッグを行うことができます。

今回はそのデバッグ方法を紹介したいと思います。
使用するWebサーバは最近お気に入りの「BrowserSync」を使っています。


今回やる事

  • WebStormのコンソールにログを出力
  • WebStormのエディタで変数/プロパティの中身をリアルタイム表示
  • WebStormでブレークポイントを設定してJavaScriptを一時停止
    → コールスタックを辿ったり、変数/プロパティの中身を調べたり


動作環境

  • Windows 7 64bit
  • WebStorm 9
    → 最近リリースされた最新版
  • JetBrains IDE Support 2.0.7
    → Chromeプラグインの最新版


準備

  1. WebStormをインストール
  2. JetBrains IDE Support - Chrome ウェブストアからプラグインをChromeにインストール
  3. BrowserSyncの環境構築
    → 以前に「複数ブラウザ/端末を同期してくれるBrowserSyncが便利」という記事を書いていますので、こちらを参考にしてもらえればと思います。


BrowserSyncの起動

デバッグに使用するWebサーバとしてBrowserSyncを起動しておきます。
URLはデフォルトのhttp://localhost:3000/で説明していきます。


WebStormの設定

WebStormで任意のプロジェクトを開き、メニューバーからRun -> Edit Configurations...をクリックし、Run/Deug Configurationsダイアログを開きます。
(以下、直訳して「実行/デバッグ構成」と記述します。)

そして、左上の+ボタンを押し、JavaScript Debugを選択します。



続いて、Nameの欄には適当な名前を入れ、URL先ほどのBrowserSyncのサーバURLBrowserはChromeを選択しておきます。

設定項目

  • Name: BrowserSync Debug
  • URL: http://localhost:3000/
  • Browser: Chrome
  • Remote URLs of local files: 特に設定なし

最後のRemote URLs of local filesはWebサーバのルートディレクトリがプロジェクトのルートディレクトリと異なる場合に設定します。

この関係が正しく設定されていると、デバッガ経由でファイルを開いた場合にローカルのファイルを参照してそのまま編集できるようになります。
逆に、正しく設定されていないとWebサーバ上のファイルを読み取り専用で開いてしまいますので注意が必要です。

今回は説明を簡略化するためにプロジェクトのルートディレクトリをWebサーバのドキュメントルートと同じにしましたので、特に設定していません。


サンプルコード

デバッガを試すためのサンプルコードは以下の通りです。

index.js
// グローバル変数
var global;

$(document).ready(function () {
    console.log("start"); // コンソール出力

    // ローカル変数
    var local;

    // set1ボタンクリックで各変数に1を代入
    $("#set1").click(function(){
        local = 1;
        global = 1;
        console.log(global, local); // コンソール出力
    });
    // set2ボタンクリックで各変数に2を代入
    $("#set2").click(function(){
        local = 2;
        global = 2;
        console.log(global, local); // コンソール出力
    });

});

HTMLのソースコードは特に載せませんが、idがset1set2になっているボタンを配置して、JavaScriptではそのボタンをクリックすると変数globallocalの値を変わるようになっています。

JSファイルはindex.jsという名前でプロジェクトのルートに置いておきます。
また、HTMLファイルはindex.htmlという名前で同じくルートに置いておきます。


デバッガの起動

次に、WebStormの画面右上辺りにある虫アイコンのボタンを押してデバッガを起動します。
左のプルダウンメニューが先ほど作ったBrowserSync Debugになっている事も念のため確認しておいてください。
今回作ったもの以外に他の「実行/デバッグ構成」も用意している場合はここから選ぶ事になります。

ちなみに、Shift+F9のショートカットを使うと現在の「実行/デバッグ構成」をデバッグモード(虫アイコン)で起動できます。


Chromeが立ち上がり、先ほど指定したBrowserSyncサーバのサイトが表示されます。

WebStormとの接続に成功していると常に黄色いバーが出るようになります。

ちなみに、Chromeのデベロッパーツールを開いてしまうと接続が解除されるので注意が必要です。
スマホなどのエミュレーターと同時に使用できないのが勿体無いですね。


WebStormのコンソールにログを出力

この状態でWebStormの画面左下辺りに目を移すと、デバッガーのConsoleタブに出力したログが表示されています。

また、ログの右側のファイル名+行番号の所をクリックすると、該当するファイルをエディタで開いてくれます。

先ほども説明しましたが、Webサーバのルートディレクトリがプロジェクトのルートディレクトリと異なる場合はRemote URLs of local filesを正しく設定してないとWebサーバ上のファイルを開いてしまうので注意してください。

ちなみに、Chromeのコンソールと違ってオブジェクトを出力しても中身を展開できないのが残念な所です。


WebStormのエディタ上に変数/プロパティの中身をリアルタイム表示

先ほどのサンプルコード(index.js)をWebStormで開き、変数の辺りにマウスカーソルを持っていくと現在の値がリアルタイムに表示できます。

最初は何も入っていないのでundefinedになっています。

ページ内のボタンを押して、変数の中身を変えてみます。

表示が1に変わりました。

サクッと変数/プロパティの中身を確認するのに便利ですね。


リアルタイムに中身を表示可能な変数/プロパティ

上の例では分かりやすくグローバル変数を表示させてみましたが、中身を表示できない場合があります。

細かい検証はしてないのですが、ルートのWindowオブジェクトから辿れるプロパティに対する記述箇所であれば中身を表示できるのではと予想をしています。


例えば、サンプルコードにあるローカル変数の中身は表示できませんでした。

Windowオブジェクトから辿れないですし、関数の実行前後ではメモリにデータが残ってなさそうです。



また、いわゆるインスタンス変数もクラスの外側であれば表示可能でしたが、

クラス内部の記述ではundefinedと表示されていました。

恐らくインスタンスが複数あった時にどの値なのか特定できないからと思われます。


上記のような変数/プロパティの中身は、この後で説明するブレークポイントを使ってJavaScriptを一時停止すれば中身を確認できるようになります。


WebStormでブレークポイントを設定してJavaScriptを一時停止

では、WebStorm上でブレークポイントを設定してJavaScriptを一時停止してみます。

エディタ上で停止させたい行の左側をクリックしてブレークポイントを設定します。
ここでは、1個目のボタンのクリック時のコールバック関数の先頭に設定してみました。


この状態で1個目のボタンを押してみます。

JavaScriptの一時停止に伴い、ブラウザ上のページがグレーアウトしました。

ちなみに、画面に表示されている(コマ送りのような)アイコンを押すと、ブラウザ側からもJavaScriptの実行を再開できます。


WebStormのエディタに目を向けるとブレークポイントの所がハイライトしています。

そして、それぞれの変数の右側に変数名と値が追記されているのが確認できます。
これは想定外だったので驚きました。さすがですね。

また、先ほどのローカル変数localもJavaScriptが一時停止して現在のスコープがはっきりしているためか、中身が(この時点ではまだundefinedですが)ちゃんと表示されています。


さらに、コンソール出力の時と同様に左下の画面に目を向けると、今度はDebuggerタブが開いています。

この画面でコールスタックを辿ったり、プロパティの中身を調べたりする事ができます。


今回は、Chrome+BrowserSyncを例にして説明しましたが、Firefox用のプラグインもあるのでブラウザをFirefoxに変えてみたり、WebサーバもXAMPPなど他のサーバを利用する事もできると思います。
自由に組み合わせが出来るのが良いですね。

また、自分は普段はTypeScriptを使ってるのですが、ソースマップを適切に設定すると同じような事ができるのも確認しています。
まだ、あまり知見が貯まってないのですが、こちらも機会があれば記事にしたいと思います。