一から勉強させてください( ̄ω ̄;)

最下級エンジニアが日々の学びをアウトプットしていくだけのブログです。

RequireJSつかってみた

今回はJavaScriptのモジュール管理ライブラリのRequireJSをつかってみました。

JavaScriptにはモジュールを管理する機能がないので、大規模プロジェクトなどで、JSファイルを分割した場合、その依存関係が心配になります。

でもこのRequireJSを使えば、依存関係にあるモジュールのみを非同期でロードしてくれるので、より安全にコードを書く事ができるようになります。


それでは早速サンプルを作成してみました。
ちなみに動作確認はMAMPつかってます。


まずディレクトリ構成はこんな感じです。

ーindex.html
ーjs
 ーmain.js
 ーAnimal.js
 ーCat.js
ーvendor
 ーrequire.js


そしてそれぞれのファイルの中身はこんな感じにしました↓

//index.html

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>Require test</title>
        <script type="text/javascript" data-main="js/main" src="vendor/require.js"></script>
</head>
<body>
</body>
</html>
//Animal.js

define(function() {
  var Animal = function(){};
  Animal.prototype.breathe = function(){
    console.log("ふーふー");
  }

  return Animal;
  
});
//Cat.js

define(["Animal"], function(Animal) {
  var Cat = function(){};
  Cat.prototype = new Animal;

  Cat.prototype.cry = function(){
    console.log("にゃにゃー");
  }

  return Cat;

});
//main.js

require(["Cat"], function(Cat){
  var cat = new Cat;

  cat.breathe();
  cat.cry();
});


それでは順にみていきます。


1、RequireJSの読み込み、data-main属性の指定

index.htmlではrequire.jsをscriptタグから読み込んで、さらに分割されたモジュールファイルを読み込むための指定をしております。

<script type="text/javascript" data-main="js/main" src="vendor/require.js"></script>

ここで大事なのがdata-main属性!!


RequireJSではファイルはbaseUrlからの相対位置にあるとするので、たとえばモジュールhogeは、baseUrl/hoge.jsにあると考えられます。


ではこのbaseUrlはどうやって決まるのか。
ここでdata-main属性の出番です。


RequireJSを読み込むscriptタグにdata-main属性がある場合、RequireJSはこの属性をみて、最初に実行するモジュールとしてそこに指定しているファイルを読み込みます。そしてそのファイルのあるディレクトリがbaseUrlになります。

今回の場合、baseUrlは"js"になりますね。


他にもrequire.configにbaseUrlを指定する方法とかもあるみたいですが、今回は割愛します。。
また、data-mainが設定されてない場合はHTMLファイル(今回だとindex.html)と同じディレクトリがbaseUrlになるみたいです。


2、Animalモジュール、Catモジュールの定義

では実際にモジュールを定義していきます。
RequireJSでモジュールを定義する方法はdefine()を使います。

まず依存するモジュールが存在しないモジュールの定義では

define(function() {
    var module = ~

    return module;

});

といった感じで書けばOKです。この場合、モジュールはこの関数の返り値になります。
もちろん関数ではなく、オブジェクトをそのまま指定することもできます。

今回のサンプルではAnimalコンストラクタを定義して、そいつをreturnしております。


次に依存するモジュールが存在するモジュールの定義はこんな感じ。

define(["baseUrl/module1"], function(module1){

    var module2 = ~ //module1が絡んだなにか。。

    return module2;
});

第一引数に依存するモジュールの配列、第二引数に関数を渡します。

依存するモジュールの読み込みが全部完了した段階で、モジュールの定義が一度だけ実行され、指定した順番で依存しているモジュールが関数の引数に渡されて行きます。

今回のサンプルではCatはAnimalを継承する(つまり依存する)コンストラクタなので、第一引数の配列にAnimalを指定します。

すると第二引数の関数の引数(ややこしくてすみません…)にAnimalが渡されるので、それを用いてCatを定義してます。

最後はreturnして、Catモジュールの定義も完了です。


3、エントリーポイント(main)
最後はエントリーポイントの定義です。今回はmain.jsになります。

define()によって定義したモジュールは当然どこかで使われなくてはなりません。
その使う方法がrequire()です。

require()の使い方は、define()とよく似ていて、第一引数に依存モジュールの指定、第二引数に実行したい関数を書いていきます。んで、一般的にはdata-mainで読み込んだエントリーポイントで使われることが多いです。

今回はmainの中で、Catモジュールを読み込んで得られるCatコンストラクタから、catインスタンスを作成。
そしてcatがもっているbreatheメソッドとcryメソッドを実行しております。(以前つくったサンプル使い回してます。。)

うまく実行でけました。


このCatはAnimalを継承しており、そのAnimalはAnimal.jsに定義してあるので、当然このモジュールのロードが失敗していると実行エラーになるはずです。ちゃんとRequireJSが機能しておるということですね!!


実際ちゃんとよめてます。
f:id:d_animal141:20130907205558p:plain


ちなみに今回、data-main="js/main"って定義しているのに、RequireJSが "/main.js"しか読みにいかず、ロードエラーが出まくったんですが、require.jsをもう一度ダウンロードし直して置き換えたらちゃんと直りましたw


なんか無駄にハマったし、なにが原因だったのか結局よくわからなかったんですが、もし同じように困っている人がいたら、一度require.jsを入れ直してみるのをお試しください!!


RequireJSはちょうど今仕事でもつかっているので、また何か分かった事があれば随時ブログに書きたいと思います。


小さな事からコツコツと。