前面一篇文章寫過一些模塊的原理和怎么實現(xiàn)模塊化兔簇,但是在具體的項目當中怎么實現(xiàn)呢。我們這里介紹下require的使用硬耍。
在介紹require之前垄琐,先簡單的介紹下AMD和CMD。
? ? ?AMD(Asynchronous Module Definition)经柴,CMD(Common Module Definition)這是這兩個詞的全稱狸窘,看起來就是模塊的定義的區(qū)別,實際上也就是在具體的應用中模塊定義的位置不同坯认。下面我們介紹require翻擒,完了應該對模塊定義的位置能有一些理解氓涣。
就像上篇文章說的,我們實現(xiàn)了模塊化陋气,將不同的模塊定義成不同的對象劳吠,不同的模塊之前互不影響,而且我們還可以去引入一些模塊的依賴關系而不是全部的一股腦的引入恩伺。require就是為了實現(xiàn)模塊化的一個工具赴背。那么使用require有哪些優(yōu)點呢椰拒?
1晶渠、異步加載,我們知道js加載放到頁面之前會阻塞頁面燃观,requirejs的執(zhí)行時在異步的回調(diào)函數(shù)里褒脯,不會阻塞頁面
2、模塊的依賴缆毁,我們可以方便的管理依賴
3番川、面向?qū)ο螅ㄟ^模塊化我們可以方便的實現(xiàn)面向?qū)ο?/p>
4脊框、文件管理颁督,當我們的依賴發(fā)生變化或者文件變化時不再需要到每一個文件里去改變這個引用,只要在改一處即可浇雹,因為其他地方都是對我們模塊定義的引用沉御。
當然還有一些其他的優(yōu)點,剛開始接觸也就先介紹這一些了昭灵,下面我們來看怎么使用require
1吠裆、引入
? ? ? ?首先得第一步的先下載require并引入到頁面
<script data-main='js/config.js' ? src='js/require.js'></script>
require.js 是我們下載的require,那么config呢烂完,當然很多也用main.js只是名字而已试疙,只是覺得用config語義看起來明確,沒錯就是配置文件抠蚣。這里的config.js可以省略后綴祝旷。
requirejs提供三個方法,requirejs嘶窄,require和define怀跛,前兩個是一樣的,一般用require护侮,我們看一個config文件
/*require.config ?
baseUrl為'js'敌完,
baseUrl指的模塊文件的根目錄,可以是絕對路徑或相對路徑
*/
require.config({
? ? ?baseUrl:'js',
? ? paths: {
? ? ? ? ? jquery:'jquery-1.8.2.min'羊初,
? ? ? ? ? moduleA:'a.js'
? ? }
});
require.config時配置模塊得一些信息滨溉,這里面有兩個屬性
baseUrl我們定義的目錄什湘,表示下面的一些文件可以從這個目錄開始。
paths是一個對象晦攒,這里面就是定義我們項目中的模塊了闽撤。前面屬性名(key值)是模塊的名字,后面的屬性(value)是模塊的文件位置.
2脯颜、模塊的定義
? ? ?上面我們定義了模塊的信息哟旗,那么這些模塊的js應該怎么寫來實現(xiàn)require的使用呢。就是用到了define方法來定義模塊栋操。我們來看一個模塊的定義闸餐。
/*define的參數(shù)為匿名函數(shù),該匿名函數(shù)返回一個對象*/
define(['jquery'],function($){
? ? return {
? ? ? ? ? a: function(){
? ? ? ? ? ? ? ? ?$("body").append("模塊A加載......");
? ? ? ? ?}
? ? }
})
define為定義模塊的方法矾芙,有三個參數(shù)舍沙,第一個參數(shù)為模塊名,一般都不用定義剔宪,第二個是數(shù)組拂铡,是當前模塊的依賴,是否依賴其他的模塊葱绒,第三個參數(shù)為回調(diào)函數(shù)感帅,一般返回值為對象。
3地淀、模塊的定義和引入是完成了下面就是模塊的使用了失球,我們看一個模塊的使用
index.js
require(['config'],function(){
? ? ?require(["jquery",'a','b','c'],function($,ma,mb,mc){
? ? ? ? ma.a();
? ? ? ? mb.a();
? ? ? ? mc.a();
? ? ?})
})
最外層是應用config的配置,內(nèi)層是模塊的使用骚秦,前面數(shù)組是依賴或者引入的模塊她倘,函數(shù)的參數(shù)是這個引入的模塊的應用時的名字,函數(shù)內(nèi)是模塊內(nèi)函數(shù)的調(diào)用作箍。
當然如果直接把模塊的使用寫在config的文件內(nèi)硬梁,可以不需要聲明config的調(diào)用。
那么是使用require的時候胞得,我們要調(diào)用的模塊必須要符合require使用的模塊的要求荧止,jquery源碼里有這么一段,所以jquery我們直接使用
if ( typeof define === "function" && define.amd ) {
? ? ?define( "jquery", [], function() {
? ? ? ? ? ? ?return jQuery;
? ? ?});
}
那么其他的沒有按照這種要求寫的模塊我們怎么使用呢阶剑,這里就要用到shim跃巡。
require.config()接受一個配置對象,這個對象除了有前面說過的paths屬性之外牧愁,還有一個shim屬性素邪,專門用來配置不兼容的模塊。具體來說猪半,每個模塊要定義(1)exports值(輸出的變量名)兔朦,表明這個模塊外部調(diào)用時的名稱偷线;(2)deps數(shù)組,表明該模塊的依賴性沽甥。
比如上面的moduleA声邦,如果我們這樣寫
define(['jquery'],function($){
? ? ? ? ? ?return {
? ? ? ? ? ? ? ? ?a: function(){
? ? ? ? ? ? ? ? ? ? ? ?$("body").append("模塊A加載......");
? ? ? ? ? ? ? ? }
? ? ? ? ? }
})
這樣寫的方式符合require模塊的寫法可以直接使用。
如果我們這樣寫呢
o = { ?
? ? ? a:function(){?
? ? ? ? ? ?$("body").append("模塊A加載......");?
? ? ? }? ?
}
也就是在這個js里只寫了個對象摆舟,并沒有返回也沒有define亥曹。
那么在config里我們就需要用到這樣的配置
require.config({
? ? ? ? ?baseUrl: 'js',
? ? ? ? paths:{
? ? ? ? ? ? ?"jquery":"jquery-2.1.0",
? ? ? ? ? ? ? "moduleA":"a",
? ? ? ? ? },
? ? ? ? ?shim:{
? ? ? ? ? ? ? ?'moduleA':{
? ? ? ? ? ? ? ? ? ? ? deps:['jquery'],
? ? ? ? ? ? ? ? ? ? ? exports:'o'
? ? ? ? ? ? ? ? }
? ? ? ? ?}
})
shim的deps是這個模塊的依賴模塊的引入,exports是這個A模塊所要使用的返回值恨诱。后面的使用不變媳瞪。
在簡單些,如果我們將A寫成這樣
function a(){
? ? ? $("body").append("模塊A加載......");
}
只是一個函數(shù)的定義呢胡野,那么我們的shim里exports就要寫成?
shim:{
? ? ? 'moduleA':{
? ? ? ? ? ? deps:['jquery'],
? ? ? ? ? ? exports:'a'
? ? ? ?}
}
這時候模塊A就是一個函數(shù)而已而不是一個對象了材失。
這里我們在看下AMD和CMD痕鳍,這里我們的模塊的引入都是在使用之前將全部的依賴的模塊引入硫豆,AMD的依賴引入是提前執(zhí)行,CMD則是就近執(zhí)行笼呆,即在使用的時候執(zhí)行熊响。
參考文檔