require.jsを使ってみた備忘録

2015年1月26日

当初はcommonJSを導入しようと思った

commonJSのModuleの部分(以下が私の認識)をぜひ使ってみたかったのだが、、、

  • 機能毎にファイルで分けてそれぞれを1モジュール化
  • モジュール内ではグローバルなexportに関数なりprototypeなりを格納
  • requireで呼び出して使用

てっきりrequireとexportの仕組みをWebアプリで実現するライブラリが用意されているのだと思い込んでいたが、そういったものは見つからず。。。(あればぜひ教えてください!)

なのでcommonJSは忘れてrequire.jsの導入に方針転換した。
いちおう方針転換の判断の理由は以下の通り

  • node.jsの開発者の方が”commonJSはもう古いよー”的な発言をしたらしい
  • commonJSの策定が思いのほか進んでない
  • なによりcommonJSを取り入れたくても入り口が分からない!
  • require.jsの具体的な情報やドキュメントが豊富

とりあえずrequire.jsを入れてみる

公式ページのドキュメント通りにmain.jsを作成して読込むモジュールの設定などをコーティング

ディレクトリ構成
js/
require.js # ダウンロードしてきたrequire.js
main.js
modules/
myMod.js
myUtil.js

'use strict'
requirejs.config({
    baseUrl: 'js/modules',
    urlArgs: 'rev=20150123a',
    paths: {
        jquery : 'jquery-1.11.1.min',
        myMod  : 'myMod',
        myUtil : 'myUtil',       
    },
    shim: {
        'myUtil': {
            deps: ['jquery']
        },
        'myMod' : {
            deps: ['jquery', 'myUtil']
        }
    }
});

//jQuery読込みと実行
requirejs(['jquery'], function($){
    if($('.TARGET').length){
        require(['myMod'], function(MyMod){
            new MyMod().init();
        });
    }
});

myMod.jsは以下のような感じ

'use strict'
define(function(){
    var myMod = function(){};
    myMod.prototype = {
        init: function() {
        }
    };
    return myMod;
});

これらを呼び出すときはhtml内で以下のようにする

  <script data-main="js/main" src="js/require.js"></script>

require.jsを使ってみて気付いた点など

1)
require.jsはモジュールを非同期で読込むということだったので、どのように動くのか気になっていた。
chromeのデバッグツールで観察すると、
require.jsを読込んだ後にmain.jsを、
main.jsないでrequireで呼ばれたモジュールを順番に一つずつ読込んでいるのを確認できた。

2)
main.jsや各モジュールを編集中にブラウザのキャッシュが聞いてなかなか変更が反映されなくなることがあった。
その解消のためにもconfigの設定でurlArgsは付けておくのが良い。ただし編集したりキャッシュが邪魔するたびにurlArgsを書き直す必要があり、なんか腑に落ちない。というか、もっと根本的な解決策があると思う。。。

3)
グローバル変数のrequirerequirejsはどういった使い分けなのだろうか?現時点では同義と理解

4)
webアプリにデプロイする際には、ロード時間の短縮や負荷削減のために全モジュールをビルドして1ファイルにしておきたい。r.jsを使えば出来るらしい?が、うまく行かなかったので要調査。

java -classpath compiler.jar:js.jar org.mozilla.javascript.tools.shell.Main r.js js/main.js
js: Couldn't read source file "js/modules/jquery-1.11.1.min.js?rev=20150123e: 
  js/modules/jquery-1.11.1.min.js?rev=20150123e (No such file or directory)".
js: uncaught JavaScript runtime exception: TypeError: $ is not a function, it is undefined.

5)
とりあえずソース全体の見通しが格段に良くなったのがよい。しばらく使いまくると思う。