模塊化編程-Assignment

問答

1.為什么要使用模塊化仁期?

網(wǎng)頁愈趨向Web應用程序,導致JavaScript的體量愈來愈大夯尽,客戶端的代碼模塊化成為迫切需求冶忱。

模塊化編程主要功能在一下方面起到積極作用:

  • 代碼維護
  • 命名沖突
  • 代碼的復用性
  • 依賴管理
2.CMD尾菇、AMD、CommonJS 規(guī)范分別指什么?有哪些應用

有了模塊派诬,我們就可以更方便地使用別人的代碼劳淆,想要什么功能,就加載什么模塊千埃。但是憔儿,這樣做有一個前提,那就是大家必須以同樣的方式編寫模塊放可。

目前,通行的Javascript模塊規(guī)范共有兩種:CommonJS和AMD朝刊。

  • CommonjJS && AMD

在服務器端耀里,一定要有模塊,與操作系統(tǒng)和其他應用程序互動拾氓,否則根本沒法編程冯挎。node.js的模塊系統(tǒng),就是參照CommonJS規(guī)范實現(xiàn)的咙鞍。也就是說CommonJS是服務器端的模塊規(guī)范

在CommonJS中房官,輸出模塊變量使用module.exports對象,module.exports 對象是模塊的對外接口续滋;
有一個全局性方法require()翰守,用于加載模塊;

//math.js

exports.add = function(x,y){
    return x+y
}

//complexAdd.js
var add  =require('math').add;
exports.addMultiply = fucntion(x,y,z){
  return add(x,y)*z
}


有了服務器端模塊以后疲酌,很自然地蜡峰,大家就想要客戶端模塊。但是朗恳,由于一個重大的局限湿颅,使得CommonJS規(guī)范不適用于瀏覽器環(huán)境(CommonJS采取同步加載方式);

瀏覽器端的模塊,不能采用"同步加載"(synchronous)粥诫,只能采用"異步加載"(asynchronous)油航。這就是AMD規(guī)范誕生的背景;

也就是說怀浆,AMD是客戶端模塊化編程的規(guī)范谊囚。

AMD是"Asynchronous Module Definition"的縮寫,意思就是"異步模塊定義"揉稚。它采用異步方式加載模塊秒啦,模塊的加載不影響它后面語句的運行。所有依賴這個模塊的語句搀玖,都定義在一個回調(diào)函數(shù)中余境,等到加載完成之后,這個回調(diào)函數(shù)才會運行。

目前芳来,主要有兩個Javascript庫實現(xiàn)了AMD規(guī)范:require.js和curl.js含末,下面以require.js進一步講解AMD的用法。

requireJS是一個工具庫即舌,主要用于客戶端的模塊管理佣盒。它可以讓客戶端的代碼分成一個個模塊,實現(xiàn)異步或動態(tài)加載顽聂,從而提高代碼的性能和可維護性肥惭。它的模塊管理遵守AMD規(guī)范(Asynchronous Module Definition)。

require.js的誕生紊搪,就是為了解決這兩個問題:
(1)實現(xiàn)js文件的異步加載蜜葱,避免網(wǎng)頁失去響應; 
(2)管理模塊之間的依賴性耀石,便于代碼的編寫和維護牵囤;

requireJS的基本思想是,通過define方法滞伟,將代碼定義為模塊揭鳞;通過require方法,實現(xiàn)代碼的模塊加載梆奈。

require.js加載


<scirpt src='js/require.js  defer async='true'  data-main='js/main'>

//defer和async可以實現(xiàn)異步加載require.js資源
//data-main屬性的作用是野崇,指定網(wǎng)頁程序的主模塊

模塊的定義
define方法用于定義模塊,RequireJS要求每個模塊放在一個單獨的文件里鉴裹。按照是否依賴其他模塊舞骆,可以分成兩種情況討論。第一種情況是定義獨立模塊径荔,即所定義的模塊不依賴其他模塊督禽;第二種情況是定義非獨立模塊,即所定義的模塊依賴于其他模塊总处。

獨立模塊情況

//math.js
define(
  function(){
      var add = function(x,y){
        return x+y;  
    };
    return  {
          add:add
      }
  }
)

非獨立模塊

//complexMuliply.js
define(['math'],function(math){
      var  add = math.add;
      var  addMultiply = function(x,y,z){
          return add(x,y)*z
    }
      return {
          addMultiply: addMultiply
    }
})

define方法的第一個參數(shù)是一個數(shù)組狈惫,它的成員是當前模塊所依賴的模塊。
define方法的第二個參數(shù)是一個函數(shù)鹦马,當前面數(shù)組的所有成員加載成功后胧谈,它將被調(diào)用。它的參數(shù)與數(shù)組的成員一一對應.這個函數(shù)必須返回一個對象荸频,供其他模塊調(diào)用菱肖。
需要注意的是,回調(diào)函數(shù)必須返回一個對象旭从,這個對象就是你定義的模塊稳强,模塊名默認就是文件名场仲。

** 模塊的加載**

模塊的加載可分為加載規(guī)范模塊和非規(guī)范模塊。

加載規(guī)范模塊

//math.js
require(['math'],function(math){
    console.log(math.add(1,1))
})

require()函數(shù)接受兩個參數(shù)退疫。
第一個參數(shù)是一個數(shù)組渠缕,表示所依賴的模塊
第二個參數(shù)是一個回調(diào)函數(shù),當前面指定的模塊都加載成功后褒繁,它將被調(diào)用亦鳞。
加載的模塊會以參數(shù)形式傳入該函數(shù),從而在回調(diào)函數(shù)內(nèi)部就可以使用這些模塊棒坏。

加載非規(guī)范模塊

require.js加載的模塊燕差,必須是按照AMD規(guī)范、用define()函數(shù)定義的模塊俊抵。但是實際上谁不,有許多庫并不符合AMD規(guī)范。

這樣的模塊在用require()加載之前徽诲,要先用require.config()方法,定義它們的一些特征吵血。

舉例來說谎替,underscore和backbone這兩個庫,都沒有采用AMD規(guī)范編寫蹋辅。如果要加載它們的話钱贯,必須先定義它們的特征。

require.config({
    shim:{
      'underscore':{
          exports:'_'
    },
    'backbone':{
        deps:['underscore',''jquery],
        exports:'Backbone'
    }
  }
})

require.config()接受一個配置對象侦另,有一個shim屬性秩命,專門用來配置不兼容的模塊。具體來說褒傅,每個模塊要定義(1)exports值(輸出的變量名)弃锐,表明這個模塊外部調(diào)用時的名稱;(2)deps數(shù)組殿托,表明該模塊的依賴性霹菊。

此外,使用require.config()方法支竹,我們可以對模塊的加載行為進行自定義旋廷。require.config()就寫在主模塊(main.js)的頭部。參數(shù)就是一個對象礼搁,這個對象的paths屬性指定各個模塊的加載路徑饶碘。

require.config({
    paths:{
        'jquery':'jquery.min',
         'underscore':'underscore.min',
         'backbone':'backbone.min'
    } 
})

上面的代碼給出了三個模塊的文件名,路徑默認與main.js在同一個目錄(js子目錄)馒吴。如果這些模塊在其他目錄扎运,比如js/lib目錄瑟曲,則有兩種寫法。

一種是逐一指定路徑绪囱。

require.config({
    paths:{
        'jquery':'lib/jquery.min',
        'underscore':'lib/underscore.min',
        'backbone':'lib/backbone.min'
    }
})

另一種則是直接改變基目錄(baseUrl)

require.config({
      baseUrl:'js/lib',
      paths:{
          'jquery':'jquery.min',
         'underscore':'underscore.min',
         'backbone':'backbone.min' 
      } 
})

優(yōu)化器r.js
requireJS提供一個基于node.js的命令行工具r.js测蹲,用來壓縮多個js文件。它的主要作用是將多個模塊文件壓縮合并成一個腳本文件鬼吵,以減少網(wǎng)頁的HTTP請求數(shù)扣甲。

  • CMD

CMD(Common Module Definition) 通用模塊定義。該規(guī)范明確了模塊的基本書寫格式和基本交互規(guī)則齿椅。該規(guī)范是在國內(nèi)發(fā)展出來的
在 CMD 規(guī)范中琉挖,一個模塊就是一個文件。代碼的書寫格式如下:

define(factory);
當 factory為對象涣脚、字符串時示辈,表示模塊的接口就是該對象、字符串遣蚀;
factory為函數(shù)時矾麻,表示是模塊的構造方法。
執(zhí)行該構造方法芭梯,可以得到模塊向外提供的接口险耀。
factory 方法在執(zhí)行時,默認會傳入三個參數(shù):require玖喘、exports 和 module:

define(function(require, exports, module) { // 模塊代碼});

//math.js
define(function(require,exports,module){
//為模塊math導出add方法    
exports.add = function(x,y){
      return x+y;
  }
})

//complexAdd.js

define(function(require,exports,module){
      var add = require('math').add;//加載math模塊
      exports.addMultiply = function(x,y,z){
          return add(x,y)*z;
    }
})

  • 小結

通行的Javascript模塊規(guī)范共有兩種CommonJS和AMD甩牺;

CommonJS是基于Node.js的服務器端的模塊化規(guī)范,AMD(異步模塊定義)是客戶端的模塊化規(guī)范累奈;

此外贬派,CMD(通用模塊定義)是在國內(nèi)發(fā)展出來的客戶端的模塊規(guī)范;

AMD 是 RequireJS 在推廣過程中對模塊定義的規(guī)范化產(chǎn)出澎媒。
CMD 是 SeaJS 在推廣過程中對模塊定義的規(guī)范化產(chǎn)出搞乏。

對于依賴的模塊,AMD是提前執(zhí)行旱幼,CMD是延遲執(zhí)行查描。
CMD 推崇依賴就近,AMD 推崇依賴前置柏卤《看如下代碼:

// CMD
define(function(require, exports, module) {
var a = require('./a')
a.doSomething()
// 此處略去 100 行
var b = require('./b') 
// 依賴可以就近書寫b.doSomething()// ... })

// AMD 默認推薦的是
define(['./a', './b'], function(a, b) { 
// 依賴必須一開始就寫好
a.doSomething()
// 此處略去 100 行
b.doSomething()...})

3.如下requirejs配置中, baseUrl 有什么作用?以什么作為基準? paths 的作用和用法是什么?
        requirejs.config({
          baseUrl: "src/js", 
//改變基目錄缘缚,這里基目錄指的是./src/js 
          paths: {
            'jquery': 'lib/bower_components/jquery/dist/jquery.min'
          }
        }
//paths的作用是指定所依賴的模塊的路徑
);
4.如下 r.js 的打包配置中 baseUrl 是什么? name 是什么
({
    baseUrl: "./src/js"http://整個打包配置文件的根目錄
    paths: {
        'jquery': 'lib/bower_components/jquery/dist/jquery.min'
    },//需要打包的模塊所在的文件路徑
    name: "main",//指明解析的入口文件
    out: "dist/js/merge.js"http://打包文件的輸出
})

r.js -o main-built.js

【r.js_demo】

//module load
//main.js
require.config({
    baseUrl:'script',
    paths:{
        math:'module/math',
        complexMultiply:'module/complexMultiply'
    }
})

require(['math'],function(math){
    console.log(math.add(7,2));
})//3

require(['complexMultiply'],function(complexMultiply){
    console.log(complexMultiply.addMultiply(1,2,3));
})//9

//define module
// module/math.js
define(function(){
    var add = function(x,y){
        return x+y
    };
    return {
        add:add
    }
})

// module/complexMultiply.js
define(['math'],function(math){
    var add = math.add;
    var addMultiply = function(x,y,z){
        return add(x,y)*z;
    }
    return {
        addMultiply:addMultiply
    }
})


//r.js config
({
    baseUrl:'.',
    paths:{
        math:'module/math',
        complexMultiply:'module/complexMultiply'
    },
    name:'main',
    out:'dist/built.js'
})

代碼

【注】
老師任務39的代碼題勾笆,我將使用模塊化編程去開發(fā)接下來的個人主頁,這里就不去重構task15的代碼了桥滨;

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末窝爪,一起剝皮案震驚了整個濱河市弛车,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蒲每,老刑警劉巖纷跛,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異邀杏,居然都是意外死亡贫奠,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門望蜡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來锥余,“玉大人丸逸,你說我怎么就攤上這事书蚪◇翱。” “怎么了?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵小泉,是天一觀的道長芦疏。 經(jīng)常有香客問我,道長微姊,這世上最難降的妖魔是什么眯分? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮柒桑,結果婚禮上,老公的妹妹穿的比我還像新娘噪舀。我一直安慰自己魁淳,他們只是感情好,可當我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布与倡。 她就那樣靜靜地躺著界逛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪纺座。 梳的紋絲不亂的頭發(fā)上息拜,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天,我揣著相機與錄音净响,去河邊找鬼少欺。 笑死,一個胖子當著我的面吹牛馋贤,可吹牛的內(nèi)容都是我干的赞别。 我是一名探鬼主播,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼配乓,長吁一口氣:“原來是場噩夢啊……” “哼仿滔!你這毒婦竟也來了惠毁?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤崎页,失蹤者是張志新(化名)和其女友劉穎鞠绰,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體飒焦,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡蜈膨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了荒给。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片丈挟。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖志电,靈堂內(nèi)的尸體忽然破棺而出曙咽,到底是詐尸還是另有隱情,我是刑警寧澤挑辆,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布例朱,位于F島的核電站,受9級特大地震影響鱼蝉,放射性物質(zhì)發(fā)生泄漏洒嗤。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一魁亦、第九天 我趴在偏房一處隱蔽的房頂上張望渔隶。 院中可真熱鬧,春花似錦洁奈、人聲如沸间唉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽呈野。三九已至,卻和暖如春印叁,著一層夾襖步出監(jiān)牢的瞬間被冒,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工轮蜕, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留昨悼,地道東北人。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓肠虽,卻偏偏與公主長得像幔戏,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子税课,可洞房花燭夜當晚...
    茶點故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內(nèi)容