head.jsのローダーを少し便利に使う拡張「head-require.js」
この記事は賞味期限切れです。(更新から1年が経過しています)
自分用に書いて使っていたのですが、わりと便利だったのでここに記しておきます。
おさらい : head.jsってなに
だいぶむかしに記事を書いたことがありましたが、 「head要素に入れるべき唯一のスクリプト」 と称している便利なスクリプトです。
cf) head要素に読み込むべき唯一のスクリプト「headjs」 | Mach3.laBlog
なにをしてくれるのかというと、
- Require.jsのようにリソースローダーとして機能する
- Modenizrのようにモダン環境向けの機能判別をしてくれる
- html5shivのように、レガシー環境でもHTML5のエレメントを使えるようにしてくれる
- レスポンシブデザイン向けに、動的にHTML要素のクラス(.lt-1024等)を設定してくれる
などなど、なかなか広い守備範囲です。 専門のスクリプトに敵わない部分もあると思いますが、「器用貧乏は美徳」をモットーとするわたくしとしてはとても他人とは思えず、大変気に入っています。
リソースローダー機能拡張の経緯
自分の中でhead.jsが最も大きな役割を果たしているのがリソースローダーの機能で、
head.js(
"scripts/jquery.js",
"scripts/underscore.js",
"scripts/backbone.js",
...
);
などとすると、渡したパスのスクリプトをまとめて読みこんでくれます。 ですが、Require.jsとの2つの大きな違いをかねてよりもどかしく思っておりました。
- スクリプトをまとめてくれるコンパイラの存在
- data-main属性でインポートしてくれるローダー
他にも、強力な依存関係解決機能などがありますが、そこまで求めるならRequire.jsを素直に使うべきでしょう。 ジェネラリストはスペシャリストをその分野において超えない物。
“head-require.js”
そこで本題ですが、そのリソースローダー周りを解決する拡張機能を書いてみました。
head-require
色々ごちゃごちゃと入っておりますが、ブラウザで使用する際の本体は dist/head-require.js あるいは dist/head-require.min.js です。
基本的な使い方
まずはHTMLで head.js と head-require.js を読み込みます。
<script src="scripts/head.js"></script>
<script src="scripts/head-require.js" data-main="scripts/main.js"></script>
ここでhead-require.jsの要素に記述した data-main 属性のスクリプトを自動的に読み込みます。 main.js の中身は、例えば次のような感じに。
head.require(
"vendors/jquery.js",
"vendors/underscore.js",
"vendors/backbone.js",
"app/myapp.js"
);
head.require() は、引数に渡したスクリプトをまとめて読み込んで順次実行していきます。 myapp.js の中身が実行される頃には、jQueryもBackboneも初期化されて使えるようになっています。 また、内部で使用している head.js() の特性上、スクリプトが実行される頃にはDOMも準備万端なのでDOM readyを待つ必要はありません。
注意事項
- スクリプトへのパスは、HTMLドキュメントではなく main.jsからの相対パス です。
- 最後の引数は、 head.js() のようにコールバックは受け取れません。
コンパイラ(Gruntタスク)
コンパイラは Grunt を使用します。 CLIも用意はしましたが、Gruntの方が色々と捗るのではないでしょうか。
まずnpmでインストールします。
$ npm install head-require
Gruntタスクの設定はこんな具合です。
module.exports = function(grunt){
grunt.npmLoadTasks("head-require");
grunt.initConfig({
headRequire: {
dist: {
options: {
},
files: {
"scripts/dest.js": "scripts/main.js"
}
}
}
});
};
中身は至って単純で、 scripts/main.js の中の head.require() に引数として渡されたファイル達を ひとつにかためたものを scripts/dest.js に突っ込んでいるだけです。
options には以下の物が渡せます。
- uglify:Boolean (false) – uglify.jsでミニファイするかどうか
- banner:String (“”) – ファイルの先頭にライセンス情報などを記したコメントをつけられます
- head:String (“head”) – headオブジェクトの名前をhead_confで変更した時に
おまけ機能
appオブジェクト
head-require.js を読み込むと、app というオブジェクトがグローバルに生えます。 名前空間のように使うもよし、必要なければそっておいてあげてください。
appオブジェクトは簡単なゲッターセッターも備えているので、 アプリケーション間で共有したい値などあれば、どうぞ。
app.set("name", "MACH3");
app.get("name"); // "MACH3";
app.set({
"name": "MACH3",
"age": 17
});
app.get(); // {"name": "MACH3", "age":17}
衝突などを避けるためにappという名前を変更したい場合は、 data-appname 属性を使用します。
<script ... data-main="scripts/main.js" data-appname="myapp"></script>
まとめ
小中規模のサイトではわりと便利に使えています。 なにぶん目下開発中なもので、他にも実験中の隠し機能とかあったりしますが、 見つけたら優しくしてあげてください。
コメント