-
Notifications
You must be signed in to change notification settings - Fork 8
WebModulePattern
このエントリでは、WebModule に使われている 実装パターン(WebModulePattern) について紹介しています。
WebModulePattern は、どこでも動作し見通しの良いモジュールを記述するためのコードパターンです。 以下のように記述すると、Browser, Node.js, Worker, NW.js で動作するモジュールを構築できます。
WebModule における GLOBAL
とは JavaScript のルート要素(window や self, global)を示す定数です。この値は WebModuleIdiom を使って導き出されます。
WebModulePattern を使って定義したモジュールは GLOBAL 直下ではなく、GLOBAL.WebModule 名前空間の下に export されます。
以下は、モジュールを定義する部分のコードを抜粋したものです。
function MyExample() { ... }
が GLOBAL.WebModule.MyExample
として export されます。
GLOBAL["WebModule"]["exports"]("MyExample", function(global) {
"use strict";
function MyExample() { ... }
return MyExample; // return entity
});
モジュールの実体(entity, この場合は function MyExample() { ... }
) を使って何か操作を行う場合は、moduleExporter と moduleClosure 関数を使い、以下のように記述してください。
(function moduleExporter(name, closure) {
"use strict";
var entity = GLOBAL["WebModule"]["exports"](name, closure);
// 初期化処理: entity に対する操作や、外部への登録処理など
return entity;
})("MyExample", function moduleClosure(global) {
"use strict";
function MyExample() { ... }
return MyExample; // return entity
});
GLOBAL
を導き出すコード や GLOBAL.WebModule.exports
関数などの共通コードは、別ファイル(WebModule.js)に記述し、MyExample.js より先にロードしておきます。
// http://git.io/WebModule
// --- global variables ------------------------------------
// https://github.com/uupaa/WebModule/wiki/WebModuleIdiom
var GLOBAL = GLOBAL || (this || 0).self || global;
// --- environment detection -------------------------------
GLOBAL.IN_NODE_OR_NW = !!GLOBAL.global;
GLOBAL.IN_BROWSER = !GLOBAL.IN_NODE_OR_NW && "document" in GLOBAL;
GLOBAL.IN_WORKER = !GLOBAL.IN_NODE_OR_NW && "WorkerLocation" in GLOBAL;
GLOBAL.IN_NODE = GLOBAL.IN_NODE_OR_NW && !/native/.test(setTimeout);
GLOBAL.IN_NW = GLOBAL.IN_NODE_OR_NW && /native/.test(setTimeout);
// --- validate and assert functions -----------------------
// https://github.com/uupaa/WebModule/wiki/Validate
GLOBAL.$type = function(value, types) { return GLOBAL["Valid"] ? GLOBAL["Valid"].type(value, types) : true; };
GLOBAL.$keys = function(value, keys) { return GLOBAL["Valid"] ? GLOBAL["Valid"].keys(value, keys) : true; };
GLOBAL.$some = function(value, candidate, ignoreCase) { return GLOBAL["Valid"] ? GLOBAL["Valid"].some(value, candidate, ignoreCase) : true; };
GLOBAL.$args = function(api, args) { if (GLOBAL["Valid"]) { GLOBAL["Valid"].args(api, args); } };
GLOBAL.$valid = function(value, api, highlihgt) { if (GLOBAL["Valid"]) { GLOBAL["Valid"](value, api, highlihgt); } };
// --- WebModule ------------------------------------------
GLOBAL.WebModule = {
exports: function(name, closure) {
var alias = name in GLOBAL ? (name + "_") : name;
var entity = alias in this ? this[alias]
: this[alias] = closure(GLOBAL);
if (typeof exports !== "undefined") {
module["exports"] = entity;
}
return entity;
}
};
古いスタイルで書かれたコードを WebModulePattern に書き直す方法 についても参照してください。
TBD: このセクションは推敲や検証が終わっていません。
WebModulePattern で書かれたコードを ES6::Modules の export に対応させるには先頭に1行追加します。
export // この行を追加
GLOBAL["WebModule"]["exports"]("MyExample", function(global) {
"use strict";
function MyExample() { ... }
return MyExample; // return entity
});