JS進級編--RequireJSモジュール化プログラミング詳細
7877 ワード
1.モジュールの書き方
モジュールプログラミングには、一般的にこのようないくつかの遷移過程があります.以下のように説明します.
オリジナルの方法
このようなやり方の欠点は明らかです.グローバル変数を汚染しています.他のモジュールと変数名が衝突しないことを保証できません.モジュールメンバーの間に直接関係が見えません.
対象の書き方
上の欠点を解決するために、モジュールをオブジェクトとして作成し、すべてのモジュールのメンバーはこのオブジェクトに入れます.
「即時実行関数」を使用して、プライベートメンバーを露出しない目的を達成できます.
拡大モード
モジュールが大きい場合、いくつかの部分に分けなければなりません.またはモジュールは他のモジュールを引き継ぐ必要があります.この場合は「拡大モード」を採用する必要があります.
幅拡大モード(Loose augmentation)
ブラウザ環境では、モジュールの各部分は通常ネットから取得されていますが、どの部分が先に読み込まれているか分かりません.前節の書き方をすれば、最初に実行した部分に空のオブジェクトが存在しない場合があります.
グローバル変数を入力
独立性はモジュールの重要な特徴であり、モジュール内部はプログラムの他の部分と直接対話しないほうがいいです.
モジュール内でグローバル変数を呼び出すためには、他の変数を明示的に入力する必要があります.
2.AMD仕様
2009年には、米国のプログラマーRyan Dahlがnode.jsプロジェクトを作成し、javascript言語をサーバー側のプログラミングに使用します.
このマークは「Javascriptモジュール化プログラミング」が正式に誕生しました.正直に言って、ブラウザの環境下では、モジュールがなくても特に大きな問題ではないです.結局、ウェブページのプログラムの複雑さは限られています.しかし、サーバー側ではモジュールが必要です.オペレーティングシステムと他のアプリケーションとの対話が必要です.そうでなければ、プログラミングできないです.
node.jsのモジュールシステムは、CommunJS仕様を参照して実現されます.Common JSには、グローバルな方法require()があります.モジュールをロードするために使用されます.数学モジュールmatch.jsがあると仮定して、下記のようにロードできます.
サーバー側のモジュールがあったら、自然にクライアントモジュールが欲しいです.そして、一つのモジュールは変更せずにサーバーとブラウザで実行できます.
しかし、重大な制限のため、CommunJS仕様はブラウザ環境には適用されません.それとも前のコードですか?ブラウザで実行すれば、大きな問題があります.分かりますか?
これはサーバー側の問題ではありません.すべてのモジュールはローカルハードディスクに保存されていますので、同時にロードが完了します.待ち時間はハードディスクの読み込み時間です.しかし、ブラウザにとっては、これは大きな問題です.モジュールはサーバー側に置いています.待つ間はネットの速度によって遅くなります.長い時間待つかもしれません.ブラウザは「仮死」状態です.
したがって、ブラウザ側のモジュールは、「同期ローディング」ができず、「非同期ローディング」しか採用できません.これがAMD仕様誕生の背景です.
AMDは「Aynchronous Module Definition」の略語で、「非同期モジュール定義」という意味です.これは非同期的な方法でモジュールをロードします.モジュールのロードは後の文の動作に影響しません.このモジュールに依存するすべての文は、一つのコールバック関数で定義されています.ロードが完了したら、このコールバック関数は実行されます.
AMDはrequire()の語句を用いてモジュールをロードしますが、Common JSとは異なり、二つのパラメータが必要です.
3.require.jsのロード
require.jsをロードしてから、 のステップに たちのコードをロードします. たち のコードファイルがmain.jsであると して、jsディレクトリの にも いています.では、 のように くだけでいいです.
require.co nfigの
require.co nfig()を ってモジュールのローディング をカスタマイズできます.require.com fig()はメインモジュールのヘッダに き みます.パラメータは つのオブジェクトです.このオブジェクトのパスは モジュールのローディングパスを します.
モジュールは のdefine を して しなければなりません.モジュールが のモジュールに しない は、define() の で できます.
はmath.jsファイルがあると して、mathモジュールを しました.それでは、math.jsはこのように きます.
define()の な :
2)require(name,name 2,calback);システムはまず でパスを します. にパスとしてbaseUrlに しないと、このjsファイルをローディングします.ローディング にソースコードから られます.var data=get ScripptData(evt); るdata.idは はLotexconmp.comです.その ははっきりしています.defineに されているnameとここで られたnameを すれば、 じように されます.だから、requireとdefineのnameは を しなければなりません.
ラベルのロードが したら、ラベルの の nameを します.
のモジュールをロード
えば、undersscoreとbackboneの のライブラリは、AMD で されていません.それらをロードするには、まず を しなければなりません.
えば、jQueryのプラグインはこのように されています.
require.jsはまた のプラグインを して、いくつかの の を します.
domreadyプラグインは、ページDOM のロードが した 、 させることができます.
:Javascriptモジュール プログラミング( ):モジュールの き Javascriptモジュール プログラミング( ):AMD Javascriptモジュール プログラミング( ):require.jsの い RequireJS define
モジュールプログラミングには、一般的にこのようないくつかの遷移過程があります.以下のように説明します.
オリジナルの方法
function m1(){
//...
}
function m2(){
//...
}
上の関数m 1()とm 2()は、モジュールを構成します.使う時は、直接呼び出してもいいです.このようなやり方の欠点は明らかです.グローバル変数を汚染しています.他のモジュールと変数名が衝突しないことを保証できません.モジュールメンバーの間に直接関係が見えません.
対象の書き方
上の欠点を解決するために、モジュールをオブジェクトとして作成し、すべてのモジュールのメンバーはこのオブジェクトに入れます.
var module1 = new Object({
_count : 0,
m1 : function (){
//...
},
m2 : function (){
//...
}
});
上の関数m 1()とm 2()は、すべてmodule 1オブジェクトにパッケージされています.使うときは、このオブジェクトの属性を呼び出します.module1.m1();
ただし、このような書き方では、モジュール全員が暴露され、内部状態は外部で書き換えられます.例えば、外部コードは内部カウンタの値を直接変更することができます.module1._count = 5;
即時実行関数の書き方「即時実行関数」を使用して、プライベートメンバーを露出しない目的を達成できます.
var module1 = (function(){
var _count = 0;
var m1 = function(){
//...
};
var m2 = function(){
//...
};
return {
m1 : m1,
m2 : m2
};
})();
上記の書き方では、外部コードは内部の_count変数を読み込めません.console.info(module1._count); //undefined
module 1はJavascriptモジュールの基本的な書き方です.以下、この書き方を加工します.拡大モード
モジュールが大きい場合、いくつかの部分に分けなければなりません.またはモジュールは他のモジュールを引き継ぐ必要があります.この場合は「拡大モード」を採用する必要があります.
var module1 = (function (mod){
mod.m3 = function () {
//...
};
return mod;
})(module1);
上のコードはmodule 1モジュールに新しい方法m 3()を追加し、新しいmodule 1モジュールに戻ります.幅拡大モード(Loose augmentation)
ブラウザ環境では、モジュールの各部分は通常ネットから取得されていますが、どの部分が先に読み込まれているか分かりません.前節の書き方をすれば、最初に実行した部分に空のオブジェクトが存在しない場合があります.
var module1 = ( function (mod){
//...
return mod;
})(window.module1 || {});
「拡大モード」に比べて、「拡大モード」は「即時実行関数」のパラメータで、空のオブジェクトでも大丈夫です.グローバル変数を入力
独立性はモジュールの重要な特徴であり、モジュール内部はプログラムの他の部分と直接対話しないほうがいいです.
モジュール内でグローバル変数を呼び出すためには、他の変数を明示的に入力する必要があります.
var module1 = (function ($, YAHOO) {
//...
})(jQuery, YAHOO);
上のmodule 1モジュールはjQueryライブラリとYUIライブラリを使用する必要があります.この2つのライブラリをパラメータとしてmodule 1に入力します.これはモジュールの独立性を保証するだけでなく、モジュール間の依存関係を明らかにします.2.AMD仕様
2009年には、米国のプログラマーRyan Dahlがnode.jsプロジェクトを作成し、javascript言語をサーバー側のプログラミングに使用します.
このマークは「Javascriptモジュール化プログラミング」が正式に誕生しました.正直に言って、ブラウザの環境下では、モジュールがなくても特に大きな問題ではないです.結局、ウェブページのプログラムの複雑さは限られています.しかし、サーバー側ではモジュールが必要です.オペレーティングシステムと他のアプリケーションとの対話が必要です.そうでなければ、プログラミングできないです.
node.jsのモジュールシステムは、CommunJS仕様を参照して実現されます.Common JSには、グローバルな方法require()があります.モジュールをロードするために使用されます.数学モジュールmatch.jsがあると仮定して、下記のようにロードできます.
var math = require('math');
その後、モジュールが提供する方法を呼び出すことができます.var math = require('math');
math.add(2,3); // 5
このシリーズは主にブラウザに対してプログラミングしていますので、node.jsには関わりません.Common JSについては多く紹介していません.ここで知っている限り、requireはモジュールをロードするのに使えばいいです.サーバー側のモジュールがあったら、自然にクライアントモジュールが欲しいです.そして、一つのモジュールは変更せずにサーバーとブラウザで実行できます.
しかし、重大な制限のため、CommunJS仕様はブラウザ環境には適用されません.それとも前のコードですか?ブラウザで実行すれば、大きな問題があります.分かりますか?
var math = require('math');
math.add(2, 3);
第二行はmart.add(2,3)で、第一行のrequire(math)の後に運行しますので、math.jsのロードが完了するまで待たなければなりません.つまり、ロード時間が長いとアプリケーション全体が停止します.これはサーバー側の問題ではありません.すべてのモジュールはローカルハードディスクに保存されていますので、同時にロードが完了します.待ち時間はハードディスクの読み込み時間です.しかし、ブラウザにとっては、これは大きな問題です.モジュールはサーバー側に置いています.待つ間はネットの速度によって遅くなります.長い時間待つかもしれません.ブラウザは「仮死」状態です.
したがって、ブラウザ側のモジュールは、「同期ローディング」ができず、「非同期ローディング」しか採用できません.これがAMD仕様誕生の背景です.
AMDは「Aynchronous Module Definition」の略語で、「非同期モジュール定義」という意味です.これは非同期的な方法でモジュールをロードします.モジュールのロードは後の文の動作に影響しません.このモジュールに依存するすべての文は、一つのコールバック関数で定義されています.ロードが完了したら、このコールバック関数は実行されます.
AMDはrequire()の語句を用いてモジュールをロードしますが、Common JSとは異なり、二つのパラメータが必要です.
require([module], callback);
最初のパラメータ[module]は、配列で、中のメンバーはロードするモジュールです.2番目のパラメータのcalbackはローディング成功後のコールバック関数です.前のコードをAMD形式に書き換えると、次のようになります.require(['math'], function (math) {
math.add(2, 3);
});
math.add()はmatchモジュールと同期していないので、ブラウザで仮死が発生しないことは明らかです.したがって、AMDはブラウザ環境に適しています.3.require.jsのロード
このファイルを み むと、ウェブページの がなくなるかもしれないと える がいます. は つあります. つはホームページの に いてロードすることです.もう つは のように くことです.
async は、このファイルは なロードが であり、Webページの が われないようにすることを しています.IEはこの をサポートしておらず、deferのみをサポートするので、deferも き みます.require.jsをロードしてから、 のステップに たちのコードをロードします. たち のコードファイルがmain.jsであると して、jsディレクトリの にも いています.では、 のように くだけでいいです.
data-main の は、ウェブプログラムのメインモジュールを します. の では、jsディレクトリの のmain.jsです.このファイルは にrequire.jsにロードされます.require.jsデフォルトのファイルの り はjsですので、main.jsを にmainと くことができます.require.co nfigの
require.co nfig()を ってモジュールのローディング をカスタマイズできます.require.com fig()はメインモジュールのヘッダに き みます.パラメータは つのオブジェクトです.このオブジェクトのパスは モジュールのローディングパスを します.
require.config({
baseUrl: "js/lib",
paths: {
"jquery": "jquery.min",
"underscore": "underscore.min",
"backbone": "backbone.min"
}
});
AMDモジュールの き モジュールは のdefine を して しなければなりません.モジュールが のモジュールに しない は、define() の で できます.
はmath.jsファイルがあると して、mathモジュールを しました.それでは、math.jsはこのように きます.
// 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));
});
このモジュールが のモジュールに する 、define の のパラメータは、モジュールの を す である があります.define(['myLib'], function(myLib){
function foo(){
myLib.doSomething();
}
return {
foo : foo
};
});
require() が のモジュールをロードすると、 にmyLib.jsファイルをロードします.define()の な :
define('sample3' ,['sample','sample1'],function (sample,sample1) {
var sample4 = require('sample4');
return function(){
alert(sample.name+':'+sample.sayhell());
}
});
define のnameとrequire の との について1)define(name,[],calback)このnameは できます.デフォルトはファイル です.もちろんカスタムしてもいいです.ソースコードによってdefine の は はこのnameと モジュール、コールバック を つの としてグローバルの グループに しています.つまりdefQue.pushです.このnameはこのコンポーネントに されたIDです.2)require(name,name 2,calback);システムはまず でパスを します. にパスとしてbaseUrlに しないと、このjsファイルをローディングします.ローディング にソースコードから られます.var data=get ScripptData(evt); るdata.idは はLotexconmp.comです.その ははっきりしています.defineに されているnameとここで られたnameを すれば、 じように されます.だから、requireとdefineのnameは を しなければなりません.
ラベルのロードが したら、ラベルの の nameを します.
のモジュールをロード
えば、undersscoreとbackboneの のライブラリは、AMD で されていません.それらをロードするには、まず を しなければなりません.
require.config({
shim: {
'underscore':{
exports: '_'
},
'backbone': {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
}
}
});
require.co nfig()は、 のpaths の に、 のないモジュールを するためのshim があります. には、 モジュールは、(1)export ( の )を し、このモジュールの び し の を します.(2)deps は、モジュールの を します.えば、jQueryのプラグインはこのように されています.
shim: {
'jquery.scroll': {
deps: ['jquery'],
exports: 'jQuery.fn.scroll'
}
}
require.jsプラグインrequire.jsはまた のプラグインを して、いくつかの の を します.
domreadyプラグインは、ページDOM のロードが した 、 させることができます.
require(['domready!'], function (doc){
// called once the DOM is ready
});
textとimageプラグインは、require.jsにテキストと ファイルのロードを します.define([
'text!review.txt',
'image!cat.jpg'
],
function(review,cat){
console.log(review);
document.body.appendChild(cat);
}
);
たようなプラグインはjsonとmdownがあります.jsonファイルとmarkdownファイルをロードするために います.:Javascriptモジュール プログラミング( ):モジュールの き Javascriptモジュール プログラミング( ):AMD Javascriptモジュール プログラミング( ):require.jsの い RequireJS define