Require.JS解決的問題:html
RequireJS的基本思想:經過define方法,將代碼定義爲模塊;經過require方法,實現代碼的模塊加載。jquery
一 採用AMD規範編寫模塊json
1.採用define()函數來定義模塊數組
@1.模塊不依賴其餘模塊,直接定義在define()函數之中瀏覽器
簡寫:生成一個擁有method1method2兩個方法的模塊dom
define({異步
method1: function(){},async
method2:function(){},函數
})工具
另外一種等價的寫法是,把對象寫成一個函數,該函數的返回值就是輸出的模塊
define(function(){
return{
method1:function(){},
method2:function(){},
};
})
後一種寫法的自由度更高一點,能夠在函數體內寫一些模塊初始化代碼
字面量寫法:
define(function (){
var add = function (x,y){
return x+y;
};
return {
add: add 前面的add對應外部調用名 後面的add對應模塊裏的實現函數名
};
});
@2.非獨立模塊:模塊還依賴其餘模塊
若是這個模塊還依賴其餘模塊,那麼define()函數的第一個參數,必須是一個數組,指明該模塊的依賴性。
define(['module1','module2'],function(m1,m2)){
.......doSomething
}
define方法的第一個參數是一個數組,它的成員是當前模塊所依賴的模塊。好比,['module1', 'module2']表示咱們定義的這個新模塊依賴於module1模塊和module2模塊,只有先加載這兩個模塊,新模塊才能正常運行。通常狀況下,module1模塊和module2模塊指的是,當前目錄下的module1.js文件和module2.js文件,等同於寫成['./module1', './module2']。
define方法的第二個參數是一個函數,當前面數組的全部成員加載成功後,它將被調用。它的參數與數組的成員一一對應,好比function(m1, m2)就表示,這個函數的第一個參數m1對應module1模塊,第二個參數m2對應module2模塊。
這個函數必須返回一個對象,供其餘模塊調用。
define(['module1', 'module2'], function(m1, m2) {
return {
method: function() {
m1.methodA();
m2.methodB();
}
};
});
上面代碼表示新模塊返回一個對象,該對象的method方法就是外部調用的接口,menthod方法內部調用了m1模塊的methodA方法和m2模塊的methodB方法。
須要注意的是,回調函數必須返回一個對象,這個對象就是你定義的模塊。
define(['myLib'], function(myLib){
function foo(){
myLib.doSomething();
}
return {
foo : foo
};
});
當require()函數加載上面這個模塊的時候,就會先加載myLib.js文件
二 模塊調用
1. 加載require.js將require.js嵌入網頁
<script src="js/require.js" defer async="true" ></script>
async屬性代表這個文件須要異步加載,避免網頁失去響應。IE不支持這個屬性,只支持defer,因此把defer也寫上
2. 加載主模塊:整個網頁的入口代碼
加載require.js之後,下一步就要加載咱們本身的代碼了。假定咱們本身的代碼文件是main.js,也放在js目錄下面。
<script data-main="scripts/main" src=" js /require.js"></script>
data-main屬性不可省略,用於指定網頁程序的主模塊,在上例中爲js子目錄下的main.js文件,這個文件會第一個被require.js加載。因爲require.js默認的文件後綴名是js,因此能夠把main.js簡寫成main。
3. 編寫主模塊
常見的狀況是,主模塊依賴於其餘模塊,這時就要使用AMD規範定義的的require()函數。
require(['moduleA', 'moduleB', 'moduleC'], function (moduleA, moduleB, moduleC){
// some code here
});
require()函數接受兩個參數。
第一個參數是一個數組,表示所依賴的模塊,上例就是['moduleA', 'moduleB', 'moduleC'],即主模塊依賴這三個模塊;
第二個參數是一個回調函數,當前面指定的模塊都加載成功後,它將被調用。加載的模塊會以參數形式傳入該函數,從而在回調函數內部就可使用這些模塊。
require()異步加載moduleA,moduleB和moduleC,瀏覽器不會失去響應;它指定的回調函數,只有前面的模塊都加載成功後,纔會運行,解決了依賴性的問題。
默認狀況下,require.js假定這三個模塊與main.js在同一個目錄,文件名分別爲jquery.js,underscore.js和backbone.js,而後自動加載。
require(['foo', 'bar'], function ( foo, bar ) {
foo.doSomething();
});
上面方法表示加載foo和bar兩個模塊,當這兩個模塊都加載成功後,執行一個回調函數。該回調函數就用來完成具體的任務。
require方法的第一個參數,是一個表示依賴關係的數組。這個數組能夠寫得很靈活,請看下面的例子。
require( [ window.JSON ? undefined : 'util/json2' ], function ( JSON ) {
JSON = JSON || window.JSON;
console.log( JSON.parse( '{ "JSON" : "HERE" }' ) );
});
上面代碼加載JSON模塊時,首先判斷瀏覽器是否原生支持JSON對象。若是是的,則將undefined傳入回調函數,不然加載util目錄下的json2模塊。
如何動態加載模塊
define(function ( require ) {
var isReady = false, foobar;
require(['foo', 'bar'], function (foo, bar) {
isReady = true;
foobar = foo() + bar();
});
4.模塊加載 require.config()方法
require.config()方法,咱們能夠對模塊的加載行爲進行自定義。
require.config()就寫在主模塊(main.js)的頭部。參數就是一個對象,這個對象的paths屬性指定各個模塊的加載路徑。
@1.路徑默認與main.js在同一個目錄
require.config({
paths: {
"jquery": "jquery.min",
"underscore": "underscore.min",
"backbone": "backbone.min"
}
});
@2.逐一指定路徑 (js/lib)
require.config({
paths: {
"jquery": "lib/jquery.min",
"underscore": "lib/underscore.min",
"backbone": "lib/backbone.min"
}
});
@3.設置基路徑 baseUrl
require.config({
baseUrl: "js/lib",
paths: {
"jquery": "jquery.min",
"underscore": "underscore.min",
"backbone": "backbone.min"
}
});
require.js要求,每一個模塊是一個單獨的js文件。這樣的話,若是加載多個模塊,就會發出屢次HTTP請求,會影響網頁的加載速度。所以,require.js提供了一個優化工具,當模塊部署完畢之後,能夠用這個工具將多個模塊合併在一個文件中,減小HTTP請求數。
return {
isReady: isReady,
foobar: foobar
};
});
上面代碼所定義的模塊,內部加載了foo和bar兩個模塊,在沒有加載完成前,isReady屬性值爲false,加載完成後就變成了true。所以,能夠根據isReady屬性的值,決定下一步的動做。
2.domready插件,可讓回調函數在頁面DOM結構加載完成後再運行。
require(['domready!'], function (doc){
// called once the DOM is ready
});