requirejs
解決兩個(gè)問(wèn)題:
1.實(shí)現(xiàn)js文件的異步加載拍顷,避免網(wǎng)頁(yè)失去響應(yīng)抚太;
2.管理模塊之間的依賴性,便于代碼的編寫和維護(hù)昔案。
使用方法:
1.官網(wǎng)下載require.js最新版本
2.下載后尿贫,假定把它放在js子目錄下面,就可以加載了
<script src="js/require.js"></script>
為避免加載這個(gè)文件可能造成網(wǎng)頁(yè)失去響應(yīng)踏揣,解決辦法有兩個(gè):
1.把它放在網(wǎng)頁(yè)底部加載
2.把它寫成:<script src="js/require.js" defer
async="true"> </script>
3.加載我們自己的代碼庆亡,假定我們自己的代碼文件是main.js,也放在js目錄下面捞稿,那么只需要寫成下面這樣就行了:
<script src="js/require.js" data-main="js/main"></script>
data-main屬性的作用是又谋,指定網(wǎng)頁(yè)程序的主模塊。在上例中娱局,就是js目錄下面的main.js彰亥,這個(gè)文件會(huì)第一個(gè)被require.js加載。由于require.js默認(rèn)的文件后綴名是js衰齐,所以可以把main.js寫成main
4.主模塊寫法:main.js主模塊任斋,就是整個(gè)網(wǎng)頁(yè)的入口代碼
如果我們的代碼不依賴任何其他模塊,那么可以直接寫入javascript代碼
//main.js
alert("加載成功耻涛!");
但這樣的話废酷,就沒(méi)必要使用require.js了,真正常見(jiàn)的情況是犬第,主模塊依賴其他模塊锦积,這時(shí)就要使用AMD規(guī)范定義require()函數(shù)。
//main.js
require(['moduleA','moduleB','moduleC'],function(moduleA,moduleB,moduleC){
//some code here
});
require()函數(shù)接受兩個(gè)參數(shù):
1.第一個(gè)參數(shù)是一個(gè)數(shù)組歉嗓,表示所依賴的模塊,即主模塊依賴['moduleA','moduleB','moduleC']這三個(gè)模塊
2.第二個(gè)參數(shù)是一個(gè)回調(diào)函數(shù)背蟆,當(dāng)前面指定的模塊都加載成功后鉴分,它將被調(diào)用。加載的模塊會(huì)以參數(shù)形式傳入該函數(shù)带膀,從而在回調(diào)函數(shù)內(nèi)部就可以使用這些模塊志珍。
require()異步加載moduleA,moduleB,moduleC,瀏覽器不會(huì)失去響應(yīng);它指定的回調(diào)函數(shù)垛叨,只有前面的模塊都加載成功后伦糯,才會(huì)運(yùn)行柜某,解決了依賴性的問(wèn)題。
例子:
require(['jquery','undescore','backbone'],function($,_,Backbone){
//some code here
});
5.模塊的加載
上面實(shí)例中敛纲,主模塊的依賴模塊是['jquery','undescore','backbone']喂击。默認(rèn)情況下,require.js假定這三個(gè)模塊與main.js在同一個(gè)目錄淤翔,文件名分別為jquery.js,underscore.js,backbone.js翰绊,然后自動(dòng)加載。
使用require.config()方法旁壮,我們可以對(duì)模塊的加載行為進(jìn)行自定義监嗜。require.config()就寫在主模塊(main.js)的頭部。參數(shù)就是一個(gè)對(duì)象抡谐,這個(gè)對(duì)象的paths屬性指定各模塊的加載路徑裁奇。
require.config({
paths:{
"jquery":"jquery.min",
"underscore":"underscore.min",
"backbone":"backbone.min"
}
});
上面的代碼給出了三個(gè)模塊的文件名,路徑默認(rèn)與main.js在同一個(gè)目錄(js子目錄)麦撵。如果這些模塊在其他目錄刽肠,比如js/lib目錄,則有兩種寫法:
1.逐一指定路徑
require.config({
paths:{
"jquery":"lib/jquery.min",
"underscore":"lib/underscore.min",
"backbone": "lib/backbone.min"
}
});
2.直接改變基目錄
require.config({
baseUrl: "js/lib",
paths: {
"jquery":"jquery.min",
"underscore":"underscore.min",
"backbone":"backbone.min"
}
});
require.js要求厦坛,每個(gè)模塊是一個(gè)單獨(dú)的js文件五垮,這樣的話,如果加載多個(gè)模塊杜秸,就會(huì)發(fā)出多次HTTP請(qǐng)求放仗,會(huì)影響頁(yè)面的加載速度。因此require提供了一個(gè)優(yōu)化工具撬碟,當(dāng)模塊部署完畢后诞挨,可以用這個(gè)工具將多個(gè)模塊合并在一個(gè)文件中,減少HTTP請(qǐng)求數(shù)呢蛤。
6.AMD模塊的寫法
require.js加載的模塊惶傻,采用AMD規(guī)范。也就是說(shuō)其障,模塊必須按照AMD的規(guī)范來(lái)寫银室。具體來(lái)說(shuō),就是模塊必須采用特定的define()函數(shù)來(lái)定義励翼。如果一個(gè)模塊不依賴其他模塊蜈敢,那么可以直接定義在define()函數(shù)中。
假定現(xiàn)在有一個(gè)math.js文件汽抚,它定義了一個(gè)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));
});
如果這個(gè)模塊還依賴其他模塊造烁,那么define()函數(shù)的第一個(gè)參數(shù)必須是一個(gè)數(shù)組否过,指明該模塊的依賴性午笛。
define(['myLib'],function(myLib){
function foo(){
myLib.doSomething();
}
return{
foo:foo
};
});
7.加載非規(guī)范的模塊
理論上,require.js加載的模塊苗桂,必須是按照AMD規(guī)范药磺、用define()函數(shù)定義的模塊。但是實(shí)際上誉察,雖然已經(jīng)有一部分流行的函數(shù)庫(kù)(比如jQuery)符合AMD規(guī)范与涡,更多的庫(kù)并不符合。那么持偏,require.js是否能夠加載非規(guī)范的模塊呢驼卖?
回答是可以的。
這樣的模塊在用require()加載之前鸿秆,要先用require.config()方法酌畜,定義它們的一些特征。
舉例來(lái)說(shuō)卿叽,underscore和backbone這兩個(gè)庫(kù)桥胞,都沒(méi)有采用AMD規(guī)范編寫。如果要加載它們的話考婴,必須先定義它們的特征贩虾。
require.config({
shim: {
'underscore':{
exports: '_'
},
'backbone': {
deps:['underscore', 'jquery'],
exports: 'Backbone'
}
}
});
require.config()接受一個(gè)配置對(duì)象,這個(gè)對(duì)象除了有前面說(shuō)過(guò)的paths屬性之外沥阱,還有一個(gè)shim屬性缎罢,專門用來(lái)配置不兼容的模塊。具體來(lái)說(shuō)考杉,每個(gè)模塊要定義(1)exports值(輸出的變量名)策精,表明這個(gè)模塊外部調(diào)用時(shí)的名稱;
(2)deps數(shù)組崇棠,表明該模塊的依賴性咽袜。
比如,jQuery的插件可以這樣定義:
shim: {
'jquery.scroll': {
deps: ['jquery'],
exports:'jQuery.fn.scroll'
}
}
8.require.js插件
require.js還提供一系列插件枕稀,實(shí)現(xiàn)一些特定的功能询刹。
domready插件,可以讓回調(diào)函數(shù)在頁(yè)面DOM結(jié)構(gòu)加載完成后再運(yùn)行萎坷。
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文件。
轉(zhuǎn)自阮一峰博客:http://www.ruanyifeng.com/blog/2012/11/require_js.html