モバイルファースト時代のWebアプリケーションデバッグ手法

買物情報事業部の前田 (@TakatoshiMaeda) です。

Webアプリケーションを開発していると、思ったようなスタイルが適用されなかったりJavaScriptの挙動が意図しないものとなっているケースがままあります。そのような時に、Chrome Developer ToolsSafari Web Inspector等を用いてスマートフォン実機に接続をしてデバッグしますが、

  • Android標準ブラウザ
  • Android/iOSアプリケーション内部のWebView*1

ではインスペクタとの連携に対応しておらず、上記ブラウザでのみ再現がされる不具合に対してはHTML/CSSの確認やJavaScriptを実行しながらのデバッグは基本的に出来ません。 weinreというデバッグツールを用いて、上記ブラウザ環境下でWebアプリケーションのデバッグを行う方法について紹介します。

weinre

weinreはNode.jsで開発されているWebアプリケーションのデバッグツールです。開発PC上でweinre serverを立ち上げ、webページに埋め込んだweinreクライアントとやりとりを行うことで、ブラウザがインスペクタに対応していない場合でもインタラクティブなデバッグが可能です。

f:id:takatoshi-maeda:20150528172447p:plain

JSConsole等類似のデバッグツールもありますが、weinreはブラウザ標準のインスペクタと似たようなインターフェースと機能を備えており違和感なく利用できることからweinreを利用しています。

開発PCと同一LANにスマートフォンが接続されている環境で、実際に実機でデバッグを行う手順を解説します。

インストールから起動まで

Node.jsがインストールされていればnpmコマンドでインストール可能です。

$ npm install -g weinre
$ weinre --boundHost $YOUR_LOCAL_IP

上記コマンドでweinreが立ち上がります。boundHostオプションの指定ですが、スマートフォンから開発サーバーにアクセスをする場合、localhostを指定してしまうとデバッグに必要なJavaScriptの取得が出来ないため、開発機のローカルIPを指定して下さい。

weinreの起動確認と、対象となるJavaScriptの埋め込み

開発機のローカルIPの8080ポートに対してブラウザでアクセスをすると、以下の画面が表示されます。

f:id:takatoshi-maeda:20150528172457p:plain

この画面が表示されれば起動しています。

ここからデバッグ対象のWebアプリケーションにデバッグコードを挿入します。

  • 対象となるスクリプトをscriptタグで事前に挿入する方法(Target Script)
  • ブックマークレットでscriptタグを動的に挿入する方法(Target Bookmarklet)

の2つの方法がありますが、今回はブックマークレットを用います。 Target Bookmarkletセクションに

Javascript:(function(e){e.setAttribute("src","http://10.0.1.9:8080/target/target-script-min.js#anonymous");document.getElementsByTagName("body")[0].appendChild(e);})(document.createElement("script"));void(0);

上記タグが生成されています。スマートフォンにコピーして、デバッグを行いたいページでアドレスバーに貼り付けて下さい。貼り付けた後、開発PC上でhttp://$YOUR_LOCAL_IP:8080/client/#anonymousにアクセスすると、インスペクタが立ち上がっています。

f:id:takatoshi-maeda:20150528172511p:plain

Targetsに対象となるサイトが表示されていれば接続に成功しています。 通常のインスペクタと同様、選択しているDOMエレメントの配置確認や動的なスタイル変更、JavaScriptの実行が可能です。

f:id:takatoshi-maeda:20150528172518p:plain

ネイティブで提供されているインスペクタと比べると手間がかかりもたつきを感じることは事実ですが、不具合の手がかりが全くない状況でバグを潰すよりも遥かに効率が良いと感じるはずです。

最後に

AndroidやiOSでは新しいバージョンのOSであれば標準でデバッグが可能となってきており取り巻く状況は改善してきています。しかし、まだまだ古い環境で利用されているユーザーさんが多いことも事実です。 この記事が問題に直面した方の開発効率化の一助となれば幸いです。

*1:AndroidはKitKat以降ではコードでデバッグオプションを有効にするとWebViewもインスペクタと接続でき、iOSは6.0以降であればXcodeでビルドし端末に転送したアプリケーションはインスペクタと接続できます

/* */ @import "/css/theme/report/report.css"; /* */ /* */ body{ background-image: url('http://cdn-ak.f.st-hatena.com/images/fotolife/c/cookpadtech/20140527/20140527163350.png'); background-repeat: repeat-x; background-color:transparent; background-attachment: scroll; background-position: left top;} /* */ body{ border-top: 3px solid orange; color: #3c3c3c; font-family: 'Helvetica Neue', Helvetica, 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', Meiryo, Osaka, 'MS Pゴシック', sans-serif; line-height: 1.8; font-size: 16px; } a { text-decoration: underline; color: #693e1c; } a:hover { color: #80400e; text-decoration: underline; } .entry-title a{ color: rgb(176, 108, 28); cursor: auto; display: inline; font-family: 'Helvetica Neue', Helvetica, 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', Meiryo, Osaka, 'MS Pゴシック', sans-serif; font-size: 30px; font-weight: bold; height: auto; line-height: 40.5px; text-decoration: underline solid rgb(176, 108, 28); width: auto; line-height: 1.35; } .date a { color: #9b8b6c; font-size: 14px; text-decoration: none; font-weight: normal; } .urllist-title-link { font-size: 14px; } /* Recent Entries */ .recent-entries a{ color: #693e1c; } .recent-entries a:visited { color: #4d2200; text-decoration: none; } .hatena-module-recent-entries li { padding-bottom: 8px; border-bottom-width: 0px; } /*Widget*/ .hatena-module-body li { list-style-type: circle; } .hatena-module-body a{ text-decoration: none; } .hatena-module-body a:hover{ text-decoration: underline; } /* Widget name */ .hatena-module-title, .hatena-module-title a{ color: #b06c1c; margin-top: 20px; margin-bottom: 7px; } /* work frame*/ #container { width: 970px; text-align: center; margin: 0 auto; background: transparent; padding: 0 30px; } #wrapper { float: left; overflow: hidden; width: 660px; } #box2 { width: 240px; float: right; font-size: 14px; word-wrap: break-word; } /*#blog-title-inner{*/ /*margin-top: 3px;*/ /*height: 125px;*/ /*background-position: left 0px;*/ /*}*/ /*.header-image-only #blog-title-inner {*/ /*background-repeat: no-repeat;*/ /*position: relative;*/ /*height: 200px;*/ /*display: none;*/ /*}*/ /*#blog-title {*/ /*margin-top: 3px;*/ /*height: 125px;*/ /*background-image: url('http://cdn-ak.f.st-hatena.com/images/fotolife/c/cookpadtech/20140527/20140527172848.png');*/ /*background-repeat: no-repeat;*/ /*background-position: left 0px;*/ /*}*/