これでできる! クロスブラウザJavaScript入門

第2回完全版:ブラウザとデバッグ環境

こんにちは、太田です。前回はクロスブラウザの入口として、各ブラウザの特徴をまとめつつ、実際にクロスブラウザなコードを紹介しました。今回はクロスブラウザ対策における基本である、各ブラウザ環境の構築について解説したいと思います。

前回紹介した通りブラウザにはたくさんの種類・バージョンがあります。それぞれが動作する環境を用意するだけでも、一苦労ではすみません。なるべく少ないマシンで、各バージョンをインストールして、さらにデバッグするための環境作りについて紹介します。なお、Safari以外はWindows環境を想定しています。さらに、特に断りがない限りはWindows XP SP3をベースに解説させていただきます。ご了承ください。

各ブラウザのデバッグ環境は近年目覚しいほどの進化を遂げています。統合デバッグ環境の草分けであるFirebugを筆頭に、Safari/Chrome(WebKit)のWeb Inspector、OperaのDragonfly、IEの開発者ツールと、それぞれDOMやオブジェクトの中身を解析したり、JavaScriptのステップ実行ができたりと、重要な機能をサポートしています。ウェブ開発者にとってはいずれも必須機能ばかりです。それぞれ長所短所もありますので、是非この機会に試していただければと思います。

IEのデバッグ環境

IEはWindowsにデフォルトでインストールされていますが、それゆえに各バージョンを用意するのに苦労します。IE 6・IE 7・IE 8と3つのバージョンでの確認が必要ですが、基本的に1つのマシンに1つのバージョンしかインストールすることができません。マシンリソースに余裕があるなら、仮想化で複数のWindowsを同時に動かしてバージョンを使い分けることが可能ですが、デバッグも行う開発環境としては少々使いにくさがあります。

仮想化以外の選択肢として、非公式で複数のバージョンを同時にインストールできるようにしたアプリケーションが公開されているので、それらを利用するという方法があります。もちろん、非公式なので完全にオリジナルと同じ動作をする保証はありませんし、セキュリティパッチの適用にも問題がありますので利用は自己責任となります。ただ、開発時や個人で使うレベルではそれほど問題ないでしょう。

Internet Explorer Collection

IEのデバッグ環境としては、IETesterなどが有名ですが、今回はInternet Explorer Collectionを紹介します。なぜIETesterではないのかといいますと、IETesterは各バージョンを並べて表示できるので、表示確認には便利ですが、JavaScriptについては少々挙動に不安があるためです。実際、IETesterでは特定のキーのイベントが取れなかったり、エラーが起きているのを捕まえ損ねたりといった問題が確認されています(2010年3月時点⁠⁠。

Internet Explorer CollectionはIE Testerと異なり、それぞれのIEが独立して動作します。本来のIEに近い形で操作することができ、原因の切り分けもしやすくなっています。もちろん、Internet Explorer Collectionにも問題がないとは限りませんから、可能であれば正規版の検証環境も用意するべきです。繰り返しになりますが、開発時の環境として必要十分と言えます。

さて、Internet Explorer CollectionはIE 1.0からIE 8.0まで同時にインストールできますが、実際にインストールするのはIE 6.0以上でよいでしょう。また、IE 6はService Pack 2以前の6.00.2800.1106と、Service Pack 2が適用された6.00.2900.2180の2つのバージョンをインストールすることができますが、基本的には6.00.2900だけで十分です。厳密には、Service Pack 3を適用するとIE 6のJScriptのバージョンが5.6から5.7に変わるので、SP3適用バージョンがほしいところではあります。JScriptのバージョンについては後述します。

IEの開発者ツール

続いて、IEの開発者ツールを簡単に紹介します。開発者ツールを使えばIE 8でJavaScriptのステップ実行やプロファイリングなどができます。ローカル変数の中身をチェックすることができますし、console.logでデバッグコンソールに変数の中身を出力することもできます。スクリプトのなかにalertを入れてデバッグするといった古典的な方法はもはや必要ありません。詳しい解説はInternet Explorer 8 の開発者ツールの概要開発者ツール : スクリプト デバッグの概要⁠、開発者ツールを使用したスクリプトのプロファイリングを参照してください。

図1 開発者ツールでのデバッグ
図1 開発者ツールでのデバッグ

しかし、この開発者ツールはIE 8用ですので、上記のInternet Explorer CollectionでインストールしたIEでは動作しません。ただ、もしVisual Studio(筆者は2008 Professional Editionで確認)がインストールされていれば、JavaScriptのエラーが発生した際にVisual StudioのデバッガでJavaScriptのデバッグを行うことが可能です。無料のExpress Editionsでは不可能なためハードルは高いですが、90日間のVisual Studio 2008 評価版もありますので、どうしてもという際は利用されてみるとよいでしょう。

IE on Virtual PC

IEでの正規の検証環境として、Virtual PC用イメージがMicrosoftから公式に公開されています。こちらでIEの各バージョンを動かすことができます。まず、Virtual PC 2007をダウンロード・インストールし、Download details: IE App Compat VHDから、検証したいバージョンのイメージファイルをダウンロードできます。

ただし、このWindowsは使用期限が設定されており、2010年3月時点で2010年4月1日までとなっています。しかし、使用期限はこれまで都度延長されているのでおそらくは当分の間は使い続けることができると思われます(未確認ですが、2010年3月時点で導入すると4月以降に再度セットアップが必要になるようです⁠⁠。

なお、このWindowsは英語版であり、初期状態では日本語を表示することができません。とはいえ、導入したバージョンに対応するOSのセットアップ用ディスクがあれば、日本語を表示させることができます。以下、IE6-XP-SP3の導入・日本語表示手順をざっくりと解説します。

まず、上記URLからダウンロードしたIE6-XP-SP3.exeファイルを実行(rarファイルの場合は解凍)してvhdファイルを適当なフォルダに保存します。Virtual PCを起動して「バーチャルマシンの作成」をウィザードに従って行い、⁠既存のバーチャルハードディスク」を選択して「バーチャルハードディスクの場所」に保存したvhdファイルを指定します。これでセットアップは完了です。

Virtual PCから起動したら、Control Panelから、Regional and Language Optionsを開き、LanguagesタブのInstall files for East Asian languagesにチェックを入れます。OKするとXPのインストールディスクを求められるので、ディスクの入ったドライブを指定してください。ただ、インストール途中でkbd106n.dllがないというエラーになるかもしれません。その場合、ディスクのi386フォルダ内にDRIVER.CABというファイルがあり、その中にkbd106n.dllが含まれているはずです。ちなみにCABはWindows標準の圧縮形式なので、そのまま開くことができます。

Firefoxのデバッグ環境

Firefoxの旧バージョンは、Firefox 旧バージョンのダウンロードから入手可能です。ただし、こちらは現在Mozillaがサポートしているバージョン限定で、Firefox 2は入手できませんし、Firefox 3.0.xのサポートも3月末で終了するため入手できなくなります。もしどうしてもより古いバージョンが必要な場合はMozilla の FTP サーバからダウンロードすることができます。

Firefoxは特殊なことをせずとも、インストール時にカスタムインストールを選び、インストールするフォルダを分ければ各バージョンをインストールすることができます。ただし、そのままでは異なるバージョンを同時に起動することができません。同時に複数のバージョンを使いたい場合は、起動オプションで -no-remote -p をつけて起動する必要があります。-pはプロファイルを指定するオプションで、プロファイル名を省略した場合、図2のようなプロファイルの選択画面が現れます。

図2 Firefoxのプロファイル
図2 Firefoxのプロファイル

プロファイルの新規作成で、そのバージョン用のプロファイルを作成し、そのプロファイルを選択して起動します。次回以降は先程の -p の後にプロファイル名を指定すれば図2の画面を省略して起動することができます。あらかじめショートカットを作成しておくとよいでしょう。

ショートカットのリンク先の例
"…\app\firefox.exe" -no-remote -p "firefox2.0.0.20"

なお、-no-remoteオプションではFirefox3.6を2つ起動するといった、ひとつのバージョンを複数のプロファイルにわけて起動することも可能です。ただし、すべてのFirefoxがno-remoteで立ち上がっていると関連付けからFirefoxを開く際にもう一つFirefoxが起動してしまうので、メインとするプロファイルを決めてno-remoteなしで起動しておくとよいでしょう。

Firebug

FirefoxでのJavaScriptのデバッグといえば、もちろんFirebugです。FirebugはHTML/CSSの解析・リアルタイム編集、コンソールでのJavaScriptの実行やステップ実行、変数やオブジェクトの中身の解析、ネットワークのログ取得にヘッダの解析、JavaScriptの実行をプロファイリング、といったことが可能な非常に高機能なデバッグ専用拡張です。さらに、Firecookie(Firebug上でCookieを監視・編集できるようにする拡張)や、YSlow(Yahoo!製のウェブサイトのパフォーマンス改善点を診断する拡張)のようなFirebugを拡張する拡張によって多彩な機能を追加することも可能です。ほかのブラウザのデバッグ環境も充実しつつある昨今ですが、このFirebugが統合的なデバッグ環境の草分けであり、デファクトスタンダードといえるツールです。

図3 Firebugのコンソール
図3 Firebugのコンソール

図3のように、複数行のJavaScriptをその場で実行する(Ctrl+Enter)こともできるので、Firebug上でJavaScriptのスニペットを書き、ある程度形になったらエディタでまとめるという方法は筆者お薦めの開発スタイルです。

ただし、Firebug自体にバグがあることも少なくなく、またFirefoxのアップデートで動かなくなるといったことも多いので、最新のバージョンをgetfirebug.comのDownloadsでチェックしておくとよいかもしれません。こちらでは関連拡張も紹介されています。

また、少し古い記事ですがFirefox 3とFirebugで始めるJavaScript開発という特集記事もあります。基本的な使い方は変わっていないので参考になるかと思います。

Safariのデバッグ環境

Safariの旧バージョンはApple - Support - Downloadsから入手できます(パスにen_USが含まれていますが、中身は日本語にも対応しているようで、ja_JPにしてダウンロードしても同じファイルのようです⁠⁠。しかし、残念ながらSafariは複数のバージョンをインストールする方法が(公式には)用意されていません。非公式でMulti-Safariを使用すれば一つのMacに複数のバージョンのSafariを動かすことができます。なお、OS XのバージョンによってSafariのバージョンも変化しますが、基本的には OS X 10.5 でSafari 3以降を検証環境とすればよいでしょう。もしSafari 2をサポートする場合は、OS X 10.4環境を用意する必要があります。

Web Inspector

Safariには、Firebugにも劣らないほど高機能なデバッガであるWeb Inspectorが標準で搭載されています。FirebugでできることのほとんどをWeb Inspectorもサポートしています。プロファイルの精度が高く、Web Storageなどにも対応していたりとFirebugよりも高機能なところも多々あります。詳しい使い方はWeb Inspector Update.ja - WebKitや、Web Inspector Redesign.ja - WebKitを参照してください。

Windows版Safari

Windows版のSafariは、特にサポートする必要はありませんが、動作確認用としてはそれなりに重宝します。ただ、最近は同じWebKitエンジンを搭載したChromeがあるので、Windows版Safariの出番はほとんどないかもしれません。

Google Chromeのデバッグ環境

Chromeはデフォルトで自動更新されるため、旧バージョンへの対応はあまり重要ではありませんが、それでも複数のバージョンでの確認は必要です。ChromeはIEと同じく複数バージョンを同時にインストールする方法は用意されていません。が、少々強引に動かすことは可能なので、その方法を紹介します。

まず、インストールしたいバージョンの詳細なバージョン番号を調べます。Chromeにはstable版、beta版、dev版と3つのリリースがありますが、通常はユーザーが使用しているのはstable版なので、安定版のリリース情報からバージョンを調べることができます。

2010年3月時点での安定版は 4.1.249.1042 です。このバージョン番号は前半2つと後半2つで独立した意味をもっています。まず前半の4はChromeのメジャーバージョン、次の1はマイナーバージョンです。一般的にはChromeのバージョンといえばこの2つのことを指します。後半の2つはChromeのリリースごとにつけられた通し番号に近いもので、前の249がブランチ、後ろの1036がそのブランチに当てられたパッチの数に相当します。2010年3月18日時点での最新ブランチは356です。

さて、後半2つが通し番号の役割を担っているので、

Chromeのインストーラー
http://dl.google.com/chrome/install/XXX.YYY/chrome_installer.exe

のXXXとYYYにそれぞれ当てはめれば、そのバージョンのインストーラーをダウンロードできます。4.1.249.1042では、

Chromeのインストーラーパス例
http://dl.google.com/chrome/install/249.1042/chrome_installer.exe

となります。このインストーラーは拡張子をexeからzipにリネームすることで、zipファイルとして解凍できます。解凍すると、なかにはchrome.7zというファイルが含まれているはずなので、このファイルを7zに対応したアーカイバ(WinRARや7-Zip、Explzhなど)でさらに解凍します。

7zファイルの中身は図4のようになっています。

図4 chrome.7zの中身
図4 chrome.7zの中身

まずChrome-binというフォルダがあり、その中にchrome.exeとwow_helper.exeという2つの実行ファイルがあり、Dictionariesというフォルダとバージョン番号のフォルダ(今回は4.1.249.1042)があります。バージョン番号のフォルダの中にchrome.exeとwow_helper.exe、Dictionariesを移動して、バージョン番号フォルダを適当なフォルダに配置します。

図5 Chromeの配置例
図5 Chromeの配置例

これでひとまず起動はできるようになりますが、このままでは正規にインストールしたChromeと同じプロファイルを使用してしまいます。そこで、起動オプションの --user-data-dirで使用するデータディレクトリを変更します。ディレクトリの指定は下記のように相対パスも使用できます。

Chromeのデータディレクトリ指定
"…\4.1.249.1042\chrome.exe" --user-data-dir="..\prof-4.1.249.1042"

こちらもFirefoxと同じくショートカットを作成しておくとよいでしょう。なお、この方法で起動したChromeが正規にインストールしたバージョンと同じであるという保証はないので、その点はご了承ください。

ChromeのWeb Inspector

ChromeにもSafariと同じくWeb Inspectorが搭載されています。ChromeのWeb Inspectorについては以前、続・先取り! Google Chrome Extensions:第6回 Firebug要らずなChromeのWeb Inspectorという記事を書いていますので、こちらを参照頂ければと思います。

なお、Chromeには拡張機能があり、その拡張としてFirebug Liteがあります。こちらがFirefoxのFirebugの代わりになるのかと思われるかもしれませんが、元々Firebug LiteはFirebugの一部の機能をブックマークレットとして利用できるようにした簡易版です。拡張としてインストールしなくてもFirebug Lite : Firebugのブックマークレットをブックマークしてもできることは同じであり、つまりは機能がブックマークレットとしてできる範囲に制限されます。機能的にはWeb Inspectorより数段劣ってしまいますので、Web Inspctorだけで十分と言えます。

Operaのデバッグ環境

Operaはインストール時にインストールするフォルダを分けることで各バージョンを別々にインストールすることができます。旧バージョンのダウンロードは、Opera ブラウザのダウンロードから取得できます。

図6 Operaの新規インストールを選択
図6 Operaの新規インストールを選択
図7 Operaのバージョンごとにフォルダを分け
図7 Operaのバージョンごとにフォルダを分け

図6図7のように新規インストールを選択して、バージョンごとにフォルダを分けるだけです。プロファイルも自動で分けてくれますので、本当にこれだけで複数のバージョンを同時に立ち上げることができます。

もし、1つのOperaを複数のプロファイルで起動したい場合、以下のように起動オプションで設定ファイルを指定して起動することでプロファイルを分けることができます。このiniファイルは実際に存在している必要はありませんが、パスは絶対パスで指定する必要があります。

Operaのプロファイル指定
"…\app\Opera 10.10\opera.exe"  /Settings "D:\opera\profile\test\opera6.ini"

OperaのDragonfly

OperaにもFirebug、Web Inspectorに似たデバッグツールがあります。Opera Dragonflyと呼ばれるツールで、Opera 9.5以降のバージョンに標準で搭載されています。モバイル版のデバッグにも対応しているというOperaらしい特徴があります。なお、DragonflyはOperaでは珍しくオープンソースであり、bitbucket.orgで公開されています。

ドキュメントはOpera Dragonfly ドキュメントから参照できますが、Opera Dragonfly 入門などは情報が古くなっている部分があるのでご注意ください。

Dragonflyは図8のようにメニューから呼び出すか、ページ内で右クリックした時のメニューから「要素を調べる」を選択すると起動します。

図8 Opera Dragonflyの起動
図8 Opera Dragonflyの起動

使い方はFirebugやWeb Inspectorとそれほど変わりません。ただ、起動後にデバッグしたいページが選択されていない場合があるので、図7のように右上のトンボのアイコンからデバッグしたいページを選択してください。

図9 Dragonflyの画面
図9 Dragonflyの画面

デバッガの基礎知識

ここまで、FirefoxのFirebug、Safari/Chrome(WebKit)のWeb Inspector、OperaのDragonfly、IEの開発者ツールと紹介してきました。これらを使いこなす上で共通のチップスがいくつかありますので紹介します。

consoleオブジェクト

各デバッガは共通してconsoleオブジェクトを実装しています(Operaは10.50以降⁠⁠。しかし、そのメソッドはブラウザごとにまちまちで、現状は次のとおりです。

consoleメソッドの実装状況(2010年3月時点)
// 共通
console.log
console.warn
console.error
console.info
// Dragonfly以外
console.assert
// Web InspectorとDragonfly以外
console.clear
// FirebugとWeb Inspector
console.count
console.debug
console.dir
console.dirxml
console.group
console.groupEnd
console.markTimeline
console.profile
console.profileEnd
console.time
console.timeEnd
console.trace
// Firebugのみ
console.exception
console.groupCollapsed

今のところ、Dragonflyが最も少なく、IEの開発者ツール、Web Inspector、Firebugの順に種類が増えています。

なお、共通といっても、Firebugの入っていないFirefoxやIE 8以前、Opera 10.50以前などはconsoleオブジェクト自体が存在しません。デバッグ用のコードを残さないように注意しましょう。

debuggerステートメント

各デバッガはJavaScriptのステップ実行をサポートしています。ブレークポイントを設定してその位置で実行を止めて、ローカル変数をチェックするといったことが可能です。

このとき、動的に追加するスクリプトなどではブレークポイントの設置が難しいケースがあります。そんなときは、debugger;という行を追加しておくとその場所でブレークすることができます。なお、debuggerはECMAScript第3版(JavaScriptのベースとなる仕様)では予約語であり、ECMAScript第5版ではキーワードとなっているので、非対応ブラウザでもシンタックスエラーになることはなく、実行時に例外を投げることになります。デバッガ(IEのスクリプトエディタやVisual Studioなど)によっては、debuggerステートメントには対応していないが、例外が起こることによってブレークさせることもできます。

プロファイリング

OperaのDragonfly以外のブラウザはJavaScriptのプロファイリング機能を搭載しています。プロファイリングでは細かい単位でパフォーマンスをチェックすることができるので、是非試行錯誤してエンジンの傾向を探ってみてください。一見些細なことに思えるような部分でも調整してみると驚くほどにパフォーマンスが上がることもあります。なお、パフォーマンスの改善はこの連載でも扱う予定です。

IEとJScriptとメモリリーク

さて、最後に少しコアなお話をしたいと思います。1ページ目で「Service Pack 3を適用するとIE 6のJScriptのバージョンが5.6から5.7に変わる」と書きました。JScript 5.7はIE 7に搭載されたJScriptと同じバージョンです。バージョンが変わっているということは、大きな変更があるのかと思われることでしょう。しかし、実際には IE 6+JScript5.7 は、XMLHttpRequest が使えるわけでもなく、style.maxHeight に対応しているというわけでもありません。特に変化はないように思われます。

と、詳細はMicrosoftの公式ドキュメントであるInternet Explorer 6 for Windows XP SP2 および Internet Explorer 6 for Windows XP SP3 で修正される問題の一覧にあります。こちらかなりの数がありますが、多くがセキュリティ修正、クラッシュやフリーズの修正です。ただ、一点だけWindows XP ベースのコンピュータで JScript スクリプトを使用する Web ページを表示すると、Internet Explorer 6 でメモリ リークが発生するという(この連載にとって)重大な修正が含まれてます。実は、この修正の通りSP3適用前のIE 6では、クロージャーを使うとメモリリークが発生していました。HTML ページの DOM オブジェクトへの循環参照はメモリ リークが発生します。にあるリークパターンはこちらです(より簡略化してあります⁠⁠。

旧IE 6でのリークパターン
<html>
<body>
<div id="menu"></div>
<script>
hookup(document.getElementById('menu'));
function hookup(element){
  element.attachEvent('onmouseover', mouse);
  function mouse (){
    // クロージャでelementへの参照が残り続ける
  }
}
</script>
</body>
</html>

このようなシンプルなスクリプトでメモリリークが発生してしまうのは深刻な問題でした。回避策はありますが、対策をするとコードが非常に冗長になってしまいます。このバグが、SP3では修正されているのです。というわけで、この連載ではSP3適用を前提として、上記のようなパターンへのメモリリーク対策は省略させて頂きます。

と、もう一点JScriptのバージョンが5.6から5.7に変わることで影響が出る問題があります。

JScriptは条件付きコンパイルを実装しており、特殊なコメントを埋め込むことができます。この条件付きコンパイルでIEかどうかの判定や、JScriptのバージョンを調べることができます。

JScriptの条件付きコンパイル
/*@cc_on alert([
  @_jscript_version,
  @_jscript_build,
  @_win32,
  @_mac
]) @*/
// 5.8, 22960, true, NaN
var isIE = false/*@cc_on || true @*/; // IEを判定

しかし、前述の通り、JScriptのバージョンは5.6→IE 6、5.7→IE 7、5.8→IE 8と対応しなくなってしまっています。条件付きコンパイルでのバージョン判定には注意が必要です。なお、こういったバージョンを判定する方法はこの連載では極力しようをさけるようにします。その詳細は次回解説します。

まとめ

今回はブラウザ環境の準備でいっぱいとなってしまいました。しかし、JavaScriptに限らずウェブ開発に欠かせないツールなので、是非試して頂ければと思います。次回からはクロスブラウザ対応の心得と、実際の作業手順を紹介していきたいと思います。

おすすめ記事

記事・ニュース一覧