JavaScriptコードのモジュール化とdojo.require()

前のページで、「dojo.require()」を用いてモジュールを動的に読み込むという例がいくつも出てきた。dojo.require()は、Dojoの特徴的な機能の一つであり、以下のような利点がある。

  • 使用するスクリプトを、メインのWebページ内で (<script>タグを使用して) 全て宣言する必要がないため、コードの可読性が向上する
  • モジュールが最初に使用されるときまで読み込みを遅延できるため、ページの初期表示が速い
  • dojo.require()を複数回呼び出しても、読み込みは最初の一回だけで済む

また、モジュールを自作することも可能だ。以下では、モジュールを自作してdojo.require()で読み込めるようにするための方法を解説する。

モジュールを作成する

ここでは、簡単なメソッド「mycom.hello.greeting()」を記述した「mycom.hello」モジュールを読み込み、使用するまでの流れを説明する。

とはいえ、モジュールと言ってもつまりは単なるJavaScriptファイルだ。とりあえず、以下の内容を記述したJavaScriptファイル「hello.js」を用意する。

 //-- (1)
 dojo.provide("mycom.hello");

 //-- (2)
 mycom.hello.greeting = function() {
   var name = dojo.byId("name");
   alert("こんにちは、" + name.value + "さん!");
 };

(1)で、Dojoのモジュールシステムにmycom.helloモジュールを「登録」している。先ほど「dojo.require()を複数回呼び出しても、読み込みは最初の一回だけ」と述べたが、それはこのdojo.provide("モジュール名")の呼び出しあってこそだ。モジュールのソース内にこの呼び出しを記述し忘れると、「モジュールが読み込めない」というエラーが発生する。

(2)で関数の定義を行う。dojo.provide()は、指定されたモジュール名からJavaScriptオブジェクトの階層 (パッケージ) を作成してくれるので (ここではmycom.hello)、そのオブジェクトのメソッドとして関数を代入している。

モジュールの作成はこれで完了だ。ポイントはdojo.provide()の呼び出しだけ。非常に簡単だ。

作成したモジュールを配置し、読み込む

さてここからが重要なのだが、作成したモジュールをどこに配置するか、というのは大きな問題だ。先に答えを言ってしまうと、以下の二つの方法がある。

  • Dojoを展開したディレクトリ内に「mycom」というディレクトリを作成し、そこにhello.jsを置く
  • サイト内の任意の場所に「mycom」というディレクトリを作成してhello.jsを置き、読み込み先をWebページ内で指定する。

最初の方法は非常に簡単だ。Dojo 1.0を展開すると「dojo-release-1.0.0」というディレクトリをルートとしたディレクトリ構造が作成されるが、その内部にモジュールを配置する。つまり、以下のような構成になるわけだ。

js/ … JavaScriptのコード置場
   |- dojo-release-1.0.0/
      |- dijit/
      |- dojo/
      |- dojox/
      |- mycom/
         |- hello.js … 先ほど作成したモジュール

こうしておけば、コード中で「dojo.require("mycom.hello")」を記述するだけでモジュールが正常に読み込まれる。

しかし、フレームワークのディレクトリ内に自作モジュールを置くことを好まない人も多いだろう。以下のような構造にしたい場合だ。

js/ … JavaScriptのコード置場
   |- dojo-release-1.0.0/
   |  |- dijit/
   |  |- dojo/
   |  |- dojox/
   |
   |- mycom/
      |- hello.js … 先ほど作成したモジュール

この場合は、Dojoに対してモジュールの検索パスを伝える必要がある。その方法は二通りある。 以下のどちらの方法を用いても構わないが、指定するパスが重要だ。モジュールの検索パスは、dojoディレクトリ (dojo.jsのあるディレクトリ) からの相対パスで指定するというルールがある。

一つ目の方法は、dojo.registerModulePath()を使用するというものだ。このメソッドは引数を二つ取り、一つ目の引数はモジュールのルート名、二つ目はモジュールのパスだ。「モジュールのルート名」とは、ピリオドで区切られたモジュール名の一番先頭の部分のことで、モジュール「mycom.hello」と「mycom.journal.example」はどちらも「mycom」となる。

// mycomモジュール階層をどこから読み込むかをDojoに伝える
dojo.registerModulePath("mycom", "../../mycom");

二つ目の方法は、djConfig.modulePathsに同様の情報を格納するというものだ。同プロパティにはJavaScriptオブジェクトを指定し、プロパティ名をモジュールのルート名、プロパティの値をモジュールのパスとして、複数のモジュールパスを指定することが可能だ。

<!-- djConfigに注目! -->
<script src="js/dojo-release-1.0.0/dojo/dojo.js"
  djConfig="modulePaths:{'mycom': '../../mycom'}"></script>