javascriptモジュール化CommonJS、AMD、CMD、UMD、ES 6
15895 ワード
これはjsモジュール化プログラミングに関する総括記録です.
ウェブサイトが次第に「インターネットアプリケーション」になるにつれて、ウェブページに埋め込まれているJavascriptコードはますます巨大になり、ますます複雑になります.
ウェブページはますますデスクトッププログラムのようになっています.チームの分担、進捗管理、ユニットテストなどが必要です.開発者はソフトウェアエンジニアリングの方法を使って、ウェブページの業務ロジックを管理しなければなりません.
Javascriptはモジュール化されたプログラミングで、すでに切実な需要になっています.理想的には、開発者は核心的な業務ロジックを実現するだけで、他の人が書いたモジュールをロードすることができます.
Javascriptコミュニティは多くの努力をして、既存の運行環境の中で、「モジュール」の効果を実現します.
Common JS
ここのCommon JS規格はCommunJS Modules/1.0仕様を指します.
Common JSはサーバー側に偏りがある仕様です.NodeJSはこの仕様を採用しています.Common JSのモジュールはスクリプトファイルです.requireコマンドは台本を初めて読み込むとスクリプト全体を実行し、メモリ内にオブジェクトを生成します.
今後このモジュールを使用する必要がある場合、exports属性に値を取ります.再度requireコマンドを実行しても、このモジュールは再実行されず、キャッシュに値を取ります.
したがって、ブラウザ側では、CommonJS仕様には適していません.だからブラウザの端にもう一つの仕様が現れました.
AMD
CommunJSはモジュール化の問題を解決しましたが、この同期ローディング方式はブラウザ側には適していません.
AMDは「Aynchronous Module Definition」の略語で、「非同期モジュール定義」です.モジュールを非同期的にロードします.モジュールのロードは、後のステートメントの動作に影響しません.ここで非同期とは、ブラウザの他のタスク(dom構築、cssレンダリングなど)をブロックしないことを指し、ロード内部は同期されている(モジュールをロードしたらすぐにフィードバックを実行する).
AMDはrequireコマンドでモジュールをロードしますが、CommunJSとは異なり、二つのパラメータが必要です.
requireJSロードモジュールは、AMD仕様を採用しています.つまり、モジュールはAMD規定の方式で書かなければなりません.
具体的には、モジュール書きは特定のdefine関数を用いて定義しなければならない.モジュールが他のモジュールに依存しない場合は、define関数に直接書き込むことができます. id:モジュールの名前で、このパラメータが提供されていない場合、モジュールの名前はデフォルトでモジュールキャリア要求の指定スクリプトの名前であるべきです. dependencies:モジュールの依存性は、モジュールによって定義されたモジュールによって識別された配列の字面量です.依存パラメータは任意であり、このパラメータを無視すると、デフォルトは factory:モジュールの工場関数であり、モジュールは実行する関数またはオブジェクトを初期化する.関数なら、一回だけ実行されるべきです.オブジェクトの場合、このオブジェクトはモジュールの出力値です. 今はmath.jsファイルがあると仮定して、mathモジュールを定義しました.それでは、math.jsの書き方は以下の通りです.
CMD
CMDは近くに依存することを推奨し、実行を遅延させる.あなたの依頼をコードの任意の行に書き込むことができます.以下の通りです.
同様にSeajsもプリロード依存jsとAMDの仕様はプリロードされている点で同じであり、明らかに異なっているところはコールとステートメント依存のところである.AMDとCMDはdifineとrequireを使用していますが、CMD標準は使用中に依存する傾向があります.つまり、コードがどこに書いてあるかに関わらず、突然他のモジュールに依存する必要があります.今のコードでrequireを導入すればいいです.規範はプリローディングを解決してくれます.しかし、AMD標準は事前にパラメータ部分に頼って書かなければなりません.これが一番明らかな違いです.
sea.jsは
Common JSはサーバー側の仕様なので、AMD、CMDの2つの基準と実際には衝突しません.
ファイルを書くときは、様々なロード仕様に対応する必要がありますが、どうすればいいですか?下のコードを見てください.
ES 6
s 6は、モジュールの入出力を
export
モジュールは独立したファイルです.ファイル内のすべての変数は、外部から取得できません.外部ファイルにこのモジュールの変数を読み込むためには、このモジュール内でexportキーを使って変数を導出する必要があります.例えば:導出関数
なお、exportから導出された変数はファイルの最上階にしかありません.ブロックレベルのスコープ内にあるとエラーが発生します.例えば:導出クラス
importコマンドは、他のモジュールのexportから導出された部分を導入することができます.
キーワードを使用します
exportがコンテンツを出力する場合、複数の変数を同時に出力するには、大かっこ
参照
AMD、CMD、CommonJS仕様をどう理解しますか?javascriptモジュール化ロード学習まとめ
AMD/CMDと先端仕様
フロントエンドモジュール化の旅(二):CommunJS、AMDとCMD
javascriptのモジュール仕様(CommunJs/AMD/CMD)を研究します.
Javascriptモジュール化プログラミング(一):モジュールの書き方
Javascriptモジュール化プログラミング(二):AMD仕様
Javascriptモジュール化プログラミング(三):require.jsの使い方
Module
ウェブサイトが次第に「インターネットアプリケーション」になるにつれて、ウェブページに埋め込まれているJavascriptコードはますます巨大になり、ますます複雑になります.
ウェブページはますますデスクトッププログラムのようになっています.チームの分担、進捗管理、ユニットテストなどが必要です.開発者はソフトウェアエンジニアリングの方法を使って、ウェブページの業務ロジックを管理しなければなりません.
Javascriptはモジュール化されたプログラミングで、すでに切実な需要になっています.理想的には、開発者は核心的な業務ロジックを実現するだけで、他の人が書いたモジュールをロードすることができます.
Javascriptコミュニティは多くの努力をして、既存の運行環境の中で、「モジュール」の効果を実現します.
Common JS
ここのCommon JS規格はCommunJS Modules/1.0仕様を指します.
Common JSはサーバー側に偏りがある仕様です.NodeJSはこの仕様を採用しています.Common JSのモジュールはスクリプトファイルです.requireコマンドは台本を初めて読み込むとスクリプト全体を実行し、メモリ内にオブジェクトを生成します.
{
id: '...',
exports: { ... },
loaded: true,
...
}
IDはモジュール名であり、exportsはモジュールが導き出すインターフェースであり、loadedはモジュールのロードが完了したかどうかを表しています.他にも多くの属性がありますが、ここでは省略されています.今後このモジュールを使用する必要がある場合、exports属性に値を取ります.再度requireコマンドを実行しても、このモジュールは再実行されず、キャッシュに値を取ります.
// math.js
exports.add = function(a, b) {
return a + b;
}
var math = require('math');
math.add(2, 3); // 5
Common JSは同期ローディングモジュールであるため、これはサーバー側にとっては問題ではなく、すべてのモジュールがローカルハードディスクに置かれているためです.モジュール待ち時間はハードディスクのファイル読み込み時間で、小さいです.しかし、ブラウザにとっては、サーバーからモジュールをロードする必要があります.インターネットの速度、代理などの理由があります.待ち時間が長いと、ブラウザは「仮死」状態になります.したがって、ブラウザ側では、CommonJS仕様には適していません.だからブラウザの端にもう一つの仕様が現れました.
AMD
CommunJSはモジュール化の問題を解決しましたが、この同期ローディング方式はブラウザ側には適していません.
AMDは「Aynchronous Module Definition」の略語で、「非同期モジュール定義」です.モジュールを非同期的にロードします.モジュールのロードは、後のステートメントの動作に影響しません.ここで非同期とは、ブラウザの他のタスク(dom構築、cssレンダリングなど)をブロックしないことを指し、ロード内部は同期されている(モジュールをロードしたらすぐにフィードバックを実行する).
AMDはrequireコマンドでモジュールをロードしますが、CommunJSとは異なり、二つのパラメータが必要です.
require([module], callback);
一番目のパラメータは「module」です.中のメンバーはロードするモジュールです.calbackはロード完了後のコールバック関数です.上記のコードをAMD方式に変更した場合:require(['math'], function(math) {
math.add(2, 3);
})
ここで、パラメータは配列のメンバーに対応します.requireJSロードモジュールは、AMD仕様を採用しています.つまり、モジュールはAMD規定の方式で書かなければなりません.
具体的には、モジュール書きは特定のdefine関数を用いて定義しなければならない.モジュールが他のモジュールに依存しない場合は、define関数に直接書き込むことができます.
define(id?, dependencies?, factory);
["require", "exports", "module"]
であるべきである.しかし、工場法の長さ属性が3未満の場合、キャリアは関数の長さ属性で指定されたパラメータの個数で工場メソッドを呼び出すように選択されます.// math.js
define(function() {
var add = function(x, y) {
return x + y;
}
return {
add: add
}
})
ロード方法は以下の通りです.// main.js
require(['math'], function(math) {
alert(math.add(1, 1));
})
mathモジュールが他のモジュールに依存している場合は、次のように書きます.// math.js
define(['dependenceModule'], function(dependenceModule) {
// ...
})
require()関数がmathモジュールをロードすると、先にdependenceModuleモジュールをロードします.複数の依存性がある場合は、すべての依存性をdefine関数の最初のパラメータ配列に書くので、AMDは前置依存である.これはCMD仕様とは違って、近くに依存しています.CMD
CMDは近くに依存することを推奨し、実行を遅延させる.あなたの依頼をコードの任意の行に書き込むことができます.以下の通りです.
define(factory)
factory
が関数の場合、モジュールの構造方法であることを示します.この構成方法を実行すると、モジュールが外部に提供するインターフェースが得られます.factoryメソッドは、実行時にデフォルトで三つのパラメータが入ります.require、exports、module.// CMD
define(function(require, exports, module) {
var a = require('./a');
a.doSomething();
var b = require('./b');
b.doSomething();
})
AMDの書き方を使うと、次のようになります.// AMD
define(['a', 'b'], function(a, b) {
a.doSomething();
b.doSomething();
})
この仕様は実際にSeajsの普及のために作られました.SeaJSを見てみます.基本的にはこの仕様が分かります.同様にSeajsもプリロード依存jsとAMDの仕様はプリロードされている点で同じであり、明らかに異なっているところはコールとステートメント依存のところである.AMDとCMDはdifineとrequireを使用していますが、CMD標準は使用中に依存する傾向があります.つまり、コードがどこに書いてあるかに関わらず、突然他のモジュールに依存する必要があります.今のコードでrequireを導入すればいいです.規範はプリローディングを解決してくれます.しかし、AMD標準は事前にパラメータ部分に頼って書かなければなりません.これが一番明らかな違いです.
sea.jsは
sea.use()
を介してモジュールをロードする.seajs.use(id, callback?)
UMDCommon JSはサーバー側の仕様なので、AMD、CMDの2つの基準と実際には衝突しません.
ファイルを書くときは、様々なロード仕様に対応する必要がありますが、どうすればいいですか?下のコードを見てください.
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD
define(['jquery', 'underscore'], factory);
} else if (typeof exports === 'object') {
// Node, CommonJS
module.exports = factory(require('jquery'), require('underscore'));
} else {
// (root window)
root.returnExports = factory(root.jQuery, root._);
}
}(this, function ($, _) {
//
function a(){}; // , ( )
function b(){}; // ,
function c(){}; // ,
//
return {
b: b,
c: c
}
}));
このコードは様々なロード仕様に対応できます.ES 6
s 6は、モジュールの入出力を
import
、export
により実現する.ここで、importコマンドは、他のモジュールが提供する機能を入力するために使用され、exportコマンドは、所定のモジュールの対外インターフェースに使用されます.export
モジュールは独立したファイルです.ファイル内のすべての変数は、外部から取得できません.外部ファイルにこのモジュールの変数を読み込むためには、このモジュール内でexportキーを使って変数を導出する必要があります.例えば:
// profile.js
export var a = 1;
export var b = 2;
export var c = 3;
下記の書き方は等価です.この方法はより明確です.var a = 1;
var b = 2;
var c = 3;
export {a, b, c}
exportコマンドは、変数を出力する以外に、関数やクラスを導出することができます.export function foo(){}
function foo(){}
function bar(){}
export {foo, bar as bar2}
上記のasは、エクスポートされた変数に名前を変更します.なお、exportから導出された変数はファイルの最上階にしかありません.ブロックレベルのスコープ内にあるとエラーが発生します.例えば:
function foo() {
export 'bar'; // SyntaxError
}
export default class {} // default
export文の出力値は、動的に結合され、そのモジュールを結合します.// foo.js
export var foo = 'foo';
setTimeout(function() {
foo = 'foo2';
}, 500);
// main.js
import * as m from './foo';
console.log(m.foo); // foo
setTimeout(() => console.log(m.foo), 500); // foo2
importimportコマンドは、他のモジュールのexportから導出された部分を導入することができます.
// abc.js
var a = 1;
var b = 2;
var c = 3;
export {a, b, c}
//main.js
import {a, b, c} from './abc';
console.log(a, b, c);
導入した変数の名前を新たに取りたい場合は、asキーワードを使用します.import {a as aa, b, c};
console.log(aa, b, c)
モジュールに先に入力してモジュールを出力したい場合、import文はexport文と一緒に書くことができます.import {a, b, c} form './abc';
export {a, b, c}
// , ,
export {a, b, c} from './abc';
モジュール全体のロードキーワードを使用します
// abc.js
export var a = 1;
export var b = 2;
export var c = 3;
// main.js
import * from as abc form './abc';
console.log(abc.a, abc.b, abc.c);
export defaultexportがコンテンツを出力する場合、複数の変数を同時に出力するには、大かっこ
{}
を使用する必要があり、同時に大かっこを導入する必要があります.export defalut
を使って出力する場合は、大かっこは不要ですが、export default
が出力する変数を入力する場合は、大かっこは不要です.// abc.js
var a = 1, b = 2, c = 3;
export {a, b};
export default c;
import {a, b} from './abc';
import c from './abc'; //
console.log(a, b, c) // 1 2 3
本質的には、export default
が出力するのはdefaultという変数または方法であり、このdefault変数を入力するときは、大きな括弧は必要ない.// abc.js
export {a as default};
// main.js
import a from './abc'; //
//
import {default as aa} from './abc';
console.log(aa);
ここまでにしましょう.サイクルローディング(モジュール相互依存)については書かれていませんが、CommunJSとES 6の処理方式は違います.参照
AMD、CMD、CommonJS仕様をどう理解しますか?javascriptモジュール化ロード学習まとめ
AMD/CMDと先端仕様
フロントエンドモジュール化の旅(二):CommunJS、AMDとCMD
javascriptのモジュール仕様(CommunJs/AMD/CMD)を研究します.
Javascriptモジュール化プログラミング(一):モジュールの書き方
Javascriptモジュール化プログラミング(二):AMD仕様
Javascriptモジュール化プログラミング(三):require.jsの使い方
Module