Closure Library 導入メモ

jQuery から Closure Library への移行を決意

jQuery は部分的に Ajax を取り入れるのには最適ですが、フル Ajax な Web アプリを開発するのは超大変。目的の UI コンポーネントを探すのも一苦労です。

その点、Closure Library は Google の Web サービスで使われている UI コンポーネントを一通り提供しているし、依存性管理やイベント機能やテスト支援機能など、大きめの Web アプリを開発するのに便利な機能が揃っています。

ただ、導入がちょっとばかり面倒なので、手順をメモしておきます。

まずは下準備

Closure Library で開発を始めるまえに、必要なツールをインストールします。

Subversion クライアントをインストール

最新の Closure Library を使うには Subversion が必要です。

開発マシンが LinuxUnix の環境なら、パッケージ管理システムで Subversion クライアントをインストールします。サーバーは不要。

Windows 環境なら TortoiseSVN か SlikSVN を導入すればいいです。

Python をインストール

Closure Library は Python で書かれたコマンドラインツールを頻繁に使います。Python は必須。パッケージ管理システムを使うか、公式サイトから Python 2.6 を入手してインストールします。

2.5 や 3.0 で動くかどうかは試していません。

プロジェクトのひな型を作成します

プロジェクトフォルダを作成
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 の導入はまた今度。