04 May 2010

JavaScript Code Modules まとめ

JavaScript Code Module について調べたのでメモ.

概要

JavaScript Code Modulesは使いまわせるjsのコードをモジュール化し, Firefoxの拡張から使えるようにしよう!という機能です. Firefox 3 (Gecko 1.9)から導入されました.

使い方

ページが見つかりません | MDNより.

まずはモジュール側のサンプルから. このようなコードを my_module.jsm という名前で作ります.

var EXPORTED_SYMBOLS = ["foo", "bar"];

function foo() {
  return "foo";
}

var bar = {
  name : "bar",
  size : "3"
};

var dummy = "dummy";

関数であろうがオブジェクトであろうが, jsのオブジェクトは何でも大丈夫です. ここで EXPORTED_SYMBOLS という配列には, エクスポートしたい(このモジュールをインポートしたコードで使いたい)オブジェクト名を入れておきます.

次は my_module.jsm を読み込んでみます.

Components.utils.import("resource://app/my_module.jsm");

alert(foo());         // "foo" と表示される
alert(bar.size + 3);  // "6" と表示される
alert(dummy);         // 'dummy' はモジュールからエクスポートされないため、 "dummy is not defined" と表示される

Components.utils.import() に読み込みたいモジュールを指定します. jsm ファイルの場所は chrome.manifest に記述します. スキーマは resource です.

resource app modules/

この他には file: スキーマが使えるそうです. chrome:// は使えないので注意が必要です.

これで現在のスコープにモジュール内で定義されているオブジェクトが読み込まれます. ここで EXPORTED_SYMBOLS で定義されているオブジェクトのみが読み込まれていることに注意してください.

基本的な使い方はこれだけです.

Components.utils.import()の第二引数

Components.utils.import() の第二引数にオブジェクトを渡すことで, モジュールがそのオブジェクトへロードされ, スコープを絞ることができます. 第二引数を省略するとモジュールからロードしたオブジェクトはグローバルスコープへ展開されます.

var scope = {};
Components.utils.import("resource://app/my_module.jsm", scope);
Application.console.log(scope.foo());  // foo
Application.console.log(foo());        // foo is not defined

Components.utils.import - Mozilla | MDN

シングルトンオブジェクトとしての動作

Components.utils.import()でインポートしたオブジェクトは初回のみ読み込まれ, 以降はキャッシュされたものが使われます. そのため色々なウィンドウややコンポーネントをまたいで値を共有するような, シングルトンのオブジェクトとして使うことも可能です.

var scope1 = {}, scope2 = {};
Components.utils.import("resource://gre/modules/JSON.jsm", scope1);
Components.utils.import("resource://gre/modules/JSON.jsm", scope2);
assert(scope2.XPCOMUtils === scope1.XPCOMUtils);  // true

(Components.utils.import - MDCより)

他の方法との比較

Performance/Addons/BestPractices - MozillaWikiにはよりよいパフォーマンスの出る拡張を開発するためのベストプラクティスが集まられています. こちらでJS Modulesにもふれられていていて, 他の方法と比べどこが優れているのかが説明されています.

  • XULの中で