jQuery から Closure Library への移行を決意
jQuery は部分的に Ajax を取り入れるのには最適ですが、フル Ajax な Web アプリを開発するのは超大変。目的の UI コンポーネントを探すのも一苦労です。
その点、Closure Library は Google の Web サービスで使われている UI コンポーネントを一通り提供しているし、依存性管理やイベント機能やテスト支援機能など、大きめの Web アプリを開発するのに便利な機能が揃っています。
ただ、導入がちょっとばかり面倒なので、手順をメモしておきます。
まずは下準備
Closure Library で開発を始めるまえに、必要なツールをインストールします。
Subversion クライアントをインストール
最新の Closure Library を使うには Subversion が必要です。
開発マシンが Linux や Unix の環境なら、パッケージ管理システムで Subversion クライアントをインストールします。サーバーは不要。
Windows 環境なら TortoiseSVN か SlikSVN を導入すればいいです。
プロジェクトのひな型を作成します
プロジェクトフォルダを作成
mkdir myproject
プロジェクト名は適当なものに変更すること。以降の作業はこのフォルダ内で行います。
Closure Library をダウンロード
Subversion を使って、Google Code のリポジトリから Closure Library の最新版をダウンロードします。
svn checkout http://closure-library.googlecode.com/svn/trunk/ closure-library
バージョンが古くても気にしないなら、Zip アーカイブをダウンロードしてもいいです。その場合は先の Subversion クライアントは不要。
scripts フォルダ作成
mkdir scripts
scripts 内に自分の JavaScript ファイルを配置します。scripts 内のフォルダ階層を名前空間と揃えると、コードを管理しやすいと思います。
app.js 作成
scripts フォルダ内に app.js を作成します。
goog.provide("myproject.App"); goog.scope(function(){ /** * myproject.App クラス。 * @constructor */ myproject.App = function() { // ここに UI 構築コードを記述する。 }; goog.addSingletonGetter(myproject.App); myproject.App.getInstance(); });
アプリケーションを表すクラスを定義しています。先頭に書いてある goog.provide は、このファイルが何を定義しているかを宣言しているものです。Closure Library が提供する依存性管理機能を使うために必要。
myproject のところは名前空間。適当なものをつけます。プロジェクト名と合わせると良いんじゃないでしょうか。ただ、名前空間にハイフン(-)を入れると goog.require で指定しても読み込まれないので要注意です。これで30分くらい悩んだorz
deps.js を作成
JavaScript ファイルの依存関係が記述された deps.js を作成するために、プロジェクトのルートで次のコマンドを実行します。
python closure-library/closure/bin/build/depswriter.py --root_with_prefix="scripts ../../../scripts" --output_file=deps.js
depswriter.py は何度も実行するので、上記コマンドをシェルスクリプトにしておくといいです。私は depsgen.sh という名前で保存し、
zsh depsgen.sh
で deps.js を生成しています。
CSS ファイル作成
scripts フォルダと同じ階層に css フォルダを作成し、その中に CSS ファイルを作成します。名前は index.css とか適当なものを付けます。CSS ファイルの内容は次の通り。
@import "../closure-library/closure/goog/css/common.css"; /* ここからアプリのスタイルを記述 */
common.css は必須。Toolbar や Menu など、使う UI コンポーネントが増えたら、import を追加します。もし import を追加し忘れると、残念な UI になってしまいます。私は意外と忘れがちです。CSS も管理してくれればいいのに。
index.html 作成
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>myproject</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <link rel="stylesheet" type="text/css" href="css/index.css"/> </head> <body> <div id="container"> <div id="header"> </div> <div id="main"> <!--ここに JavaScript で構築した UI を挿入する--> </div> </div> <script type="text/javascript" src="closure-library/closure/goog/base.js"></script> <script type="text/javascript" src="deps.js"></script> <script type="text/javascript"> goog.require("myproject.App"); </script> </body> </html>
必ず goog.require を使って App クラスを読み込むこと。script タグの src に app.js を直接指定すると、正しい順番で JavaScript ファイルが読み込まれません。
Web Application Framework のテンプレートエンジンを使うなら、テンプレートファイルに上記のコードを書くことになります。
プロジェクトのひな型はこんな感じ
myproject │ deps.js │ depsgen.sh │ index.html │ ├─closure-library │ 省略 │ ├─css │ index.css │ └─scripts app.js
あとは
デバッグしつつ開発を進めていきます。ブラウザで index.html を表示してエラーがでなければ OK。「名前空間が存在しない」というエラーが発生した場合、その名前空間を定義した JavaScript ファイルに構文エラーがあるかもしれません。
開発が終わったら Closure Compiler を使って JavaScript ファイルの結合&最適化を行うんですが、Closure Compiler の導入はまた今度。