その1で最終目標と掲げたjqueryの魔法のビルド方法をめげずに解読していたらなんか見えてきたので先にその解説。

ビルドの鍵はこのファイル。タスクランナーとしてGruntが登場するけど、ビルドの心臓部はrequire.js(r.js)で行われていることが冒頭部から分かる。

じゃあその設定はどうなっているんだとconfigのプロパティを眺めてみると、onBuildWrite: convertなるものが設定されている。

実はこれr.jsの機能で、ビルドした内容からさらに変換を加える事ができるらしい。つまりこれが設定されていなければビルドされたjqueryファイルにはdefinerequireが普通に登場する。

さらに行を下って行くと、convert関数の定義がされている。
正規表現使いまくって何やら変換しているということは分かる、分からない、試してみたほうが速い。

例えばこんなファイルを用意する。
[bbb.js]

define([], function(){  
    var bbb = {
        b: "b",
    };
    return bbb;
});

内容には全く意味は無い、とにかくこれをjqueryと同じonBuildWrite: convert設定の基でビルドしてみる(Grunt関連っぽい部分とrdefineEndの定義をファイル冒頭から持ってくれば普通にr.jsだけでビルドできました)。

結果はこうなる

    var bbb = {
        b: "b",
    };

!!!

なんとAMD特有の記述が綺麗さっぱり削除される。
ちなみにvar a = require('./bbb');という風なモジュール定義内でのrequireは特に何も変化しない。

この変換の意図を理解するために、jqueryのjQuery($)的なもの用意しておいてこんな風にモジュールを作ってみる(イメージを掴みやすいようにjqueryっぽくの実装)。

まずコア部分 [core.js]

define([], function(){  
    var jQuery = {};
    return jQuery;
});

先ほどのbbb.jsも少し改造
[bbb.js]

define(['./core'], function(jQuery){  
    jQuery.bbb = {
        b: "b",
    };
    return jQuery.bbb;
});

上記2ファイルへの参照を持つモジュールも用意する。
jqueryに倣ってグローバル展開用の処理を付けたけど、他モジュール全てへの参照さえ設定しておけばよい。

[jquery.js]

define(['./core', './bbb'], function(jQuery){  
    return ( window.jQuery = window.$ = jQuery );
});

そしてjquery.jsにさっき試したのと同じ設定でr.jsビルドを行う。

どん

    var jQuery = {};

    jQuery.bbb = {
        b: "b",
    };

    return ( window.jQuery = window.$ = jQuery );

はい、これがjqueryのビルドファイルがrequire.jsに依存せず、definerequireも登場しない仕組みです。あとはこの記述の前後に必要なものをconcatすれば公開用のビルドファイルが完成する(そのあたりは本当に貼り付けてるだけなので省略)。

天下のjquery様だけど、どうしても一言だけ言いたい。
いや口にだすのは恐れ多いからせめて念じたい。

(ふざけるな)

力技じゃねーか。
結局のところモジュール間の依存関係が解決するようにr.jsで並び替えて、あとはいらなくなったrequire.js向けのAMD記述を消し去ってしまえばお目当てのビルドが完成するという仕組み。

少し考えればわかるがこのビルドを成立させるためには守らなければならない記述方法が結構ある。だってモジュールの内容に関係なく正規表現によりAMD記述を消し去っているわけなのだから。

正直なところ、このビルド方法を採用する気にはなれない。せっかくモジュールという疎結合な仕組みを提供してくれる救世主が登場したのに、いい感じにビルドするためとはいえ、なぜモジュール外の余計なことを意識してくてはいけないのか。

しかし現実としてあのjqueryがこのビルド方法を採用しているのだ。こんな一般人でも思い当たるような諸問題なんて当然全て把握したうえであのjquery様がこのビルド方法を採用しているのだ。その意味は、推して知るべしだろう。

javascriptのさらなる発展を祈るばかり。