読者です 読者をやめる 読者になる 読者になる

そこそこ規模が大きくても何とかなるjavascriptの設計(URL dispatcherの薦め)

javascript

弁当生活始めました。agoです。

以前のjavascriptの開発はサーバサイドと同じPGが開発することが多く、機能をファイル単位で分割してそのページで必要なファイルのみを読み込むと言うことが行われていました。

ただ、最近はサーバサイドとクライアントサイドの分業が進んだことや表示速度の兼ね合いもあり、単一ファイルに全体を記述しサーバサイドでは全ページでその一ファイルのみを読み込むような形になることが多いです。

単一ファイルの利点としてはサーバサイドの実装に依存せずに任意の機能を追加できることがありますが、欠点として機能毎の切り分けが難しくなると言う点があります。

jQueryを使用して$('.selector')で切り出す方法もありますが、マークアップの全体像を正確に把握できていないと不要なページで間違って実行されてしまう危険性もあります。

そこで、以下のようなJSを先に読み込み、各URL毎に機能を切り出して実装することにより上記の問題を解決することが出来ます。

// 第一引数はURLのパス部分にマッチする正規表現 
dispatcher('.', function () {
    $(function () {
        // 全URLで使う内容 
    });
});

// 第一引数はURLのパス部分にマッチする正規表現 
dispatcher('^/hoge', function () {
    $(function () {
        // /hogeで使う内容 
    });
});

// 第一引数はURLのパス部分にマッチする正規表現 
dispatcher('^/hoge|^/huga', function () {
    $(function () {
        // /hogeと、/hugaで使う内容 
    });
});

// ライブラリ等を読み込む 

function dispatcher (path, func) {
    dispatcher.path_func = dispatcher.path_func || []
    if (func) return dispatcher.path_func.push([path, func]);
    for(var i = 0, l = dispatcher.path_func.length; i < l; ++i) { // >
        var func = dispatcher.path_func[i];
        var match = path.match(func[0]);
        match && func[1](match);
    };
};
dispatcher(location.pathname);

実質10行なので好きに使ってもらってかまいませんが、気になる方はMITライセンス、BSDライセンス、GPLライセンスのいずれかのライセンスでご利用ください。
Twitterでライセンスに関して質問があったので追記します。

この方法であれば「このコードはどのページで実行されているのか」がJS本体に記述されるため、後々機能追加する場合対象のページ以外への影響を最小に抑えることが出来ます。

問題点としてサーバサイドだけでJSの機能が追加できないという問題はありますが、、ある程度分業が行われている状況であれば有効な方法だと考えています。

カヤックでは分業になれた技術者も募集しています!

(2010/08/11 ライセンスに関して追記しました)