一、為什么要用require.js?
最早的時候,所有Javascript代碼都寫在一個文件里面,只要加載這一個文件就夠了。后來,代碼越來越多,一個文件不夠了,必須分成多個文件,依次加載。下面的網頁代碼,相信很多人都見過。
<script src="1.js"></script>
<script src="2.js"></script>
<script src="3.js"></script>
<script src="4.js"></script>
<script src="5.js"></script>
<script src="6.js"></script>
這段代碼依次加載多個js文件。
這樣的寫法有很大的缺點。首先,加載的時候,瀏覽器會停止網頁渲染,加載文件越多,網頁失去響應的時間就會越長;其次,由於js文件之間存在依賴關系,因此必須嚴格保證加載順序(比如上例的1.js要在2.js的前面),依賴性最大的模塊一定要放到最后加載,當依賴關系很復雜的時候,代碼的編寫和維護都會變得困難。
require.js的誕生,就是為了解決這兩個問題:
(1)實現js文件的異步加載,避免網頁失去響應;
(2)管理模塊之間的依賴性,便於代碼的編寫和維護。
二、require.js的加載(index.html或是product.html中的代碼)
使用require.js的第一步,是先去官方網站下載最新版本。
下載后,假定把它放在js子目錄下面,就可以加載了。
<script src="js/require.js"></script>
有人可能會想到,加載這個文件,也可能造成網頁失去響應。解決辦法有兩個,一個是把它放在網頁底部加載,另一個是寫成下面這樣:
<script src="js/require.js" defer async="true" ></script>
async屬性表明這個文件需要異步加載,避免網頁失去響應。IE不支持這個屬性,只支持defer,所以把defer也寫上。
加載require.js以后,下一步就要加載我們自己的代碼了。假定我們自己的代碼文件是main.js,也放在js目錄下面。那么,只需要寫成下面這樣就行了:
<script src="js/require.js" data-main="js/main"></script>
data-main屬性的作用是,指定網頁程序的主模塊。在上例中,就是js目錄下面的main.js,這個文件會第一個被require.js加載。由於require.js默認的文件后綴名是js,所以可以把main.js簡寫成main。
三、模塊的加載(main.js文件中的代碼)
一種則是直接配置目錄(baseUrl 要求所有的js文件都放在同一個文件夾目錄下,如這里都放在js文件下)。
require.config({
baseUrl: "js",
<!-- baseUrl,它的作用就是,以它作為基礎路徑,在這個路徑之下,查找文件。我是將所有.js文件都放在js文件夾下的。
所以,在require([])或者define([])的依賴數組列表中,寫上依賴的文件路徑:如require(['jquery','lunbo','car'],function($,l,c){ })
-->
});
require(['jquery', 'car', 'lunbo',/*依賴的文件路徑*/], function ($, car, l,/*依賴模塊返回的對象或數組*/){
// some code here
//調用依賴模塊中的屬性或方法
})
二種則是配置路徑(paths 路徑可以是絕對路徑,相對路徑,或是遠程路徑,不要求js文件都放同一個文件夾里面)
require.config({
paths: {
<!-- paths的作用呢?就是將一些常用的js文件,換成通用的名字。
例如jquery-1.8.2.min.js,我們不可能每次調用它時,都寫這一啪啦吧,
所以為了方便,就將jquery替代jquery-1.8.2.min.js咯(給路徑起別名),以后我們就可以直接使用jquery(別名)了,快捷方便。 -->
"jquery": ["jquery","https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min"],
"car":"car",
"lunbo":"lunbo",
"erro":"erro",
"glass":"../放大鏡",
"preloading":"../圖片預加載"
}
});
require(['jquery', 'glass', 'lunbo','preloading'/*依賴的文件別名*/], function ($, gla, l,prelo/*依賴模塊返回的對象或數組*/){
// some code here
//調用依賴模塊中的屬性或方法
})
三種則是一二兩種的結合
require.config({
baseUrl:'js',
paths:{
"glass":"../放大鏡",
"preloading":"../圖片預加載"
}
})
require(['jquery','car','lunbo','glass','preloading'],function($,car,l,gla,prelo){//回調函數中的參數一 一對應依賴模塊返回的對象或函數
l.move();//lunbo.js模塊返回的是對象
car();//car.js模塊返回的是函數
})
五、標准模塊的定義(define())
1 :模塊必須采用特定的define()函數來定義
如:lunbo.js文件中的代碼
define(['jquery'],function($){
return{
"move":function(){
$("#a").html("lunbo中執行的代碼");
}
}
})
如:car.js文件中的代碼
define(['jquery','lunbo'],function($,l){
return function shoping(){
console.log("car中執行的代碼")
l.move()//lunbo.js模塊返回的是對象
}
})
<!--
define!它的作用是,定義一個js模塊,供其他模塊或者require使用。
它引用其他js的模塊的方法和require差不多,都是將需要的js文件引入,然后參數一一對應。
大家需要要注意的是,define里定義的方法或者變量,其他模塊是訪問不到的,
所以,你如果想其他模塊也能訪問,就應該返回(return)對象或者函數都可以。
在這里,我return的是一個對象,提供init供其他模塊調用。
-->
六 非標准化的模塊(erro.js中的代碼)
定義的模塊不使用define()函數定義的 都是非標准模塊
如:function sucess(){
console.log("非標准模塊中執行的代碼")
}
//非標准模塊中定義的函數 ,由於沒有以函數或是對象的形式返回,所以在其他的模塊中無法訪問
//如果想訪問非標准模塊中的函數 就必須在require.config()中進行配置
如: require.config({
baseUrl:'js',
paths:{
'glass':"../放大鏡",
"preloading":"../圖片與加載"
},
shim{
"erro":{//需要配置的模塊名稱
exports:'sucess'//非標准模塊的函數名
}
}
})
require(['erro'],function(er){
er();//erro.js返回的是當個函數
})
定義的模塊不使用define()函數定義的 都是非標准模塊
如:function sucess(){
console.log("非標准模塊中執行的代碼1")
}
function madol(){
console.log("非標准模塊中執行的代碼2")
}
//非標准模塊中定義的函數 ,由於沒有以函數或是對象的形式返回,所以在其他的模塊中無法訪問
//如果想訪問非標准模塊中的函數 就必須在require.config()中進行配置
如: require.config({
baseUrl:'js',
paths:{
'glass':"../放大鏡",
"preloading":"../圖片與加載"
},
shim{
"erro":{//需要配置的模塊名稱
init:function(){
return { //配置多個非標准模塊的函數名
su:sucess,//注意此時的函數名不用引號
mo:madol
}
}
}
}
})
require(['erro'],function(er){
er.su();//erro.js返回的是對象
er.mo();
})