🧊

Requirejsを使う時の覚書

巷ではあまり評判よくないんですかね?
個人としては、そこまでらいふちぇいんじんぐってほどではないけども、
それなりに使えるケースもあると思うんですけど・・。

というわけで、個人的にメモっておきます。

シングルトンを作る

割とよくあるケースだと思います。

define([], function() {

  var MyModule = function() {
    // ...
  };

  // newして返す
  return (new MyModule());
});

こうすると一応どこでrequireしても同じものが返ってくるように。
ただ厳密には、getInstanceみたいなメソッド作って、
明示的に初期化できるようにしてから運用したほうが幸せになれる感がある。

require/defineの違い

違いがないようで違う。

define([], function() {
  // ...
});

require([], function() {
  // ...
});

HTMLにscriptタグ書いて、data-mainを指定してるうちは、全部defineで定義してても動く。
が、そのままrjsで固めてしまうと、起動メソッドが存在しない扱いになって、起動しないままになる。

循環参照を避ける

これも割とよくあるやつ。

define(['hoge'], function(Hoge) {
  // Hoge // => undefined
  // ってなってダメなやつに関しては、
});

define([], function() {
  // 使いたいときに呼ぶようにする
  var Hoge = require('hoge')
});

require.config

こいつは別ファイルにもできるけど、data-mainで指定する先にしとくのが得策。

require.config({
  paths: {},
  shim: {},

  callback: function() {}
});

みたく、実はコールバックが指定できるので、こっから全てを起動するみたくするのが良い。
そうしておけば、HTMLの記述もすっきりするし、rjsで固めるシーンになっても安心。

configを切り出すときは

とはいえそういうケースももちろんあるわけで。

詳しくは書かないけど、configをファイルで切り出す = 複数のアプリで共通のconfigを使いたい場合に、
grunt-contrib-requirejsとかの指定で、configそのまま使えなくて困る。
正確には、configの内容だけをファイル指定するオプションがない(?)

なので、そのような場合に備えて、

;(function(global) {

  var config = {
    // ...
  };
  
  if (_Node) {
    module.exports = config;
  }
  if (_Browser) {
    global.require = config;
  }

}(this.self || global));

みたく、普段使い(Browser)もGrunt(Node)もOKにしておく。
するとGruntのタスクないでrequireとかしてpaths/shimの設定を引っこ抜ける。

pathsに外部URL

使えるんですコレが。

paths: {
  facebook: 'http://connect.facebook.net/ja_JP/sdk'
},
shim: {
  facebook: { exports: 'FB' }
}

って風にできるので、わざわざこういうのだけCDN経由で云々しなくて良い。

けど、rjsで固めることを考えると、bowerなり手動なり手元に持ってこないとダメです。
rjsが取ってきてくれたりはしません。

以上、お世話になりました。