サーチ…
ユニバーサルモジュール定義(UMD)
UMD(ユニバーサルモジュール定義)パターンは、当社のモジュールを多数の異なるモジュールローダ(例えば、AMD、CommonJS)によってインポートする必要がある場合に使用されます。
パターン自体は2つの部分で構成されています。
ユーザーが実装しているモジュールローダーをチェックするIIFE(Immediately-Invoked Function Expression)。これには2つの引数があります。
root
(this
グローバルスコープを参照)とfactory
(私達は私達のモジュールを宣言する機能)。モジュールを作成する無名関数。これは第2引数としてパターンのIIFE部分に渡されます。この関数は、モジュールの依存関係を指定するために任意の数の引数を渡します。
以下の例では、AMD、次にCommonJSを確認します。これらのローダーのどちらも使用されていない場合は、モジュールとその依存関係をグローバルに利用できるようになります。
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(['exports', 'b'], factory);
} else if (typeof exports === 'object' && typeof exports.nodeName !== 'string') {
// CommonJS
factory(exports, require('b'));
} else {
// Browser globals
factory((root.commonJsStrict = {}), root.b);
}
}(this, function (exports, b) {
//use b in some fashion.
// attach properties to the exports object to define
// the exported module properties.
exports.action = function () {};
}));
直ちに呼び出される関数式(IIFE)
すぐに呼び出された関数式を使用して、公開APIを生成しながらプライベートスコープを作成することができます。
var Module = (function() {
var privateData = 1;
return {
getPrivateData: function() {
return privateData;
}
};
})();
Module.getPrivateData(); // 1
Module.privateData; // undefined
詳細については、 モジュールパターンを参照してください。
非同期モジュール定義(AMD)
AMDは、CommonJSや匿名の閉鎖など、他のシステムと共通する問題のいくつかに対処しようとするモジュール定義システムです。
AMDはこれらの問題を次のように解決します。
- define()を直ちに実行するのではなく、それを呼び出すことによってファクトリ関数を登録する
- モジュール名の配列として依存関係を渡し、ロードします。グローバルを使用する代わりに
- すべての依存関係がロードされて実行されると、ファクトリ関数の実行のみ
- ファクトリ関数への引数として依存モジュールを渡す
ここで重要なことは、モジュールが依存関係を持つことができ、開発者が複雑なコードを書かなくても、ロードを待っている間にすべてを保持することができないことです。
AMDの例は次のとおりです。
// Define a module "myModule" with two dependencies, jQuery and Lodash
define("myModule", ["jquery", "lodash"], function($, _) {
// This publicly accessible object is our module
// Here we use an object, but it can be of any type
var myModule = {};
var privateVar = "Nothing outside of this module can see me";
var privateFn = function(param) {
return "Here's what you said: " + param;
};
myModule.version = 1;
myModule.moduleMethod = function() {
// We can still access global variables from here, but it's better
// if we use the passed ones
return privateFn(windowTitle);
};
return myModule;
});
モジュールは名前をスキップして匿名にすることもできます。それが完了すると、通常はファイル名でロードされます。
define(["jquery", "lodash"], function($, _) { /* factory */ });
依存関係をスキップすることもできます。
define(function() { /* factory */ });
一部のAMDローダーでは、モジュールをプレーンオブジェクトとして定義できます。
define("myModule", { version: 1, value: "sample string" });
CommonJS - Node.js
CommonJSは、Node.jsで使用されている一般的なモジュール化パターンです。
CommonJSシステムは、他のモジュールをロードするrequire()
関数と、モジュールが一般にアクセス可能なメソッドをエクスポートできるようにするexports
プロパティを中心としています。
CommonJSの例ですが、LodashとNode.jsのfs
モジュールをロードします:
// Load fs and lodash, we can use them anywhere inside the module
var fs = require("fs"),
_ = require("lodash");
var myPrivateFn = function(param) {
return "Here's what you said: " + param;
};
// Here we export a public `myMethod` that other modules can use
exports.myMethod = function(param) {
return myPrivateFn(param);
};
module.exports
を使用してモジュール全体として関数をエクスポートすることもできます:
module.exports = function() {
return "Hello!";
};
ES6モジュール
ECMAScript 6では、モジュール構文(インポート/エクスポート)を使用すると、各ファイルは専用の名前空間を持つ独自のモジュールになります。トップレベルの関数と変数は、グローバル名前空間を汚染しません。関数、クラス、および他のモジュールの変数をインポートするために、exportキーワードを使用できます。
注:これはJavaScriptモジュールを作成するための公式な方法ですが、現在主要なブラウザではサポートされていません。ただし、ES6モジュールは多くのトランスパイラでサポートされています。
export function greet(name) {
console.log("Hello %s!", name);
}
var myMethod = function(param) {
return "Here's what you said: " + param;
};
export {myMethod}
export class MyClass {
test() {}
}
モジュールの使用
モジュールのインポートは、パスを指定するだけで簡単です。
import greet from "mymodule.js";
greet("Bob");
これは、 mymodule.js
ファイルからmyMethod
メソッドのみをインポートします。
モジュールからすべてのメソッドをインポートすることもできます:
import * as myModule from "mymodule.js";
myModule.greet("Alice");
メソッドを新しい名前でインポートすることもできます:
import { greet as A, myMethod as B } from "mymodule.js";
ES6モジュールの詳細については、 モジュールのトピックを参照してください。