web前端-深入(4)-AMD_CMD_RequireJS

題目1: 為什么要使用模塊化还蹲?

  • 解決命名沖突
  • 依賴管理
  • 提高代碼可讀性
  • 代碼解耦,提高復(fù)用性

題目2: CMD耙考、AMD谜喊、CommonJS 規(guī)范分別指什么?有哪些應(yīng)用

  1. CommonJS

1倦始、CommonJS 是用于服務(wù)器端模塊的規(guī)范斗遏。Node.js采用了這個規(guī)范。Node.JS首先采用了js模塊化的概念鞋邑。
2诵次、定義模塊:根據(jù)CommonJS規(guī)范,一個單獨的文件就是一個模塊枚碗。每一個模塊都是一個單獨的作用域逾一,也就是說,在該模塊內(nèi)部定義的變量肮雨,無法被其他模塊讀取遵堵,除非定義為global對象的屬性。
3怨规、模塊輸出:模塊只有一個出口陌宿,module.exports對象,我們需要把模塊希望輸出的內(nèi)容放入該對象波丰。
4壳坪、加載模塊: 加載模塊使用require方法,該方法讀取一個文件并執(zhí)行掰烟,返回文件內(nèi)部的module.exports對象爽蝴。

//模塊定義 myModel.js
var name = 'Byron';
function printName(){
    console.log(name);
}
function printFullName(firstName){
    console.log(firstName + name);
}
module.exports = {                //module.exports對象是作為模塊出口,方便其他的js調(diào)用
    printName: printName,
    printFullName: printFullName
}

//加載模塊
var nameModule = require('./myModel.js');       //相當(dāng)于nameModule調(diào)用了JS的require函數(shù)沐批,文件擴展名可省略,該方法讀取一個文件并執(zhí)行霜瘪,返回內(nèi)部的module.exports對象珠插。
nameModule.printName();
//用法:將模塊定義和加載模塊代碼分別放在兩個js文件中(a.js,b.js),然后在bash中執(zhí)行代碼node b.js颖对,結(jié)果會在bash中顯示 

缺點:
1捻撑、require("./myModel.js")里的路徑很不好處理
2、當(dāng)執(zhí)行require("./myModel.js")時缤底,瀏覽器要先下載文件顾患,由于是同步運行,所以要等到文件下載完成時才能執(zhí)行个唧,但是CommonJS只支持服務(wù)器端運行江解,不支持瀏覽器運行

  1. AMD

1、AMD是"Asynchronous Module Definition"的縮寫徙歼,意思就是"異步模塊定義"犁河。
2、它采用異步方式加載模塊魄梯,模塊的加載不影響它后面語句的運行桨螺。
3、所有依賴這個模塊的語句酿秸,都定義在一個回調(diào)函數(shù)中灭翔,等到加載完成之后,這個回調(diào)函數(shù)才會運行辣苏。
4肝箱、由于不是JavaScript原生支持,使用AMD規(guī)范進行頁面開發(fā)需要用到對應(yīng)的庫函數(shù)稀蟋,也就是RequireJS煌张,實際上AMD 是 RequireJS 在推廣過程中對模塊定義的規(guī)范化的產(chǎn)出
5、requireJS主要解決兩個問題:1. 多個js文件可能有依賴關(guān)系糊治,被依賴的文件需要早于依賴它的文件加載到瀏覽器唱矛。2. js加載的時候瀏覽器會停止頁面渲染,加載文件越多井辜,頁面失去響應(yīng)時間越長。

//格式:

//定義模塊:
define(id?, dependencies?, factory);    //?表示可選
//id:可選參數(shù)管闷,用來定義模塊的標(biāo)識粥脚,若沒有提供,默認(rèn)為腳本文件名(去掉拓展名)
//dependencies:是一個當(dāng)前模塊依賴的模塊名稱數(shù)組包个,默認(rèn)為["require", "exports", "module"]刷允,若factory的參數(shù)小于3冤留,加載器會選擇參數(shù)個數(shù)調(diào)用工廠方法。
//factory:工廠方法树灶,模塊初始化要執(zhí)行的函數(shù)或?qū)ο笙伺H魹楹瘮?shù),只被執(zhí)行一次天通。若為對象泊窘,應(yīng)該為模塊的輸出值

//在頁面上使用require函數(shù)加載模塊:
require([dependencies], function(){});
//第一個參數(shù)是數(shù)組,表示所依賴的模塊
//第二個參數(shù)是回調(diào)函數(shù)像寒,當(dāng)前面的模塊都加載成功后將被調(diào)用烘豹。加載的模塊會以參數(shù)形式傳入該函數(shù),從而在回調(diào)函數(shù)內(nèi)部就可以使用這些模塊
//require()函數(shù)在加載依賴模塊時是異步加載的诺祸,這樣瀏覽器不會失去響應(yīng)携悯,它的回調(diào)函數(shù)只有模塊都加載成功后才運行,解決了依賴性的問題筷笨。

//例如:
 require(['math'], function (math) {
    math.add(2, 3);
  });
  1. CMD

1憔鬼、CMD(Common Module Definition) 通用模塊定義。該規(guī)范明確了模塊的基本書寫格式和基本交互規(guī)則胃夏。該規(guī)范是在國內(nèi)發(fā)展出來的轴或。AMD是依賴關(guān)系前置,CMD是按需加載构订。
2侮叮、就像AMD有個requireJS,CMD有個瀏覽器的實現(xiàn)SeaJS悼瘾,SeaJS要解決的問題和requireJS一樣囊榜,只不過Sea.js 推崇一個模塊一個文件,遵循統(tǒng)一的寫法

//定義模塊
     define(id?, deps?, factory)
//CMD推崇一個文件一個模塊亥宿,所以經(jīng)常就用文件名作為模塊id卸勺,一般不寫
//CMD推崇依賴就近,所以一般不在define的參數(shù)中寫依賴烫扼,在factory中寫曙求,所以deps參數(shù)省略
//factory: function(require, exports, module){},require 是一個方法映企,接受模塊標(biāo)識作為唯一參數(shù)悟狱,用來獲取其他模塊提供的接口。exports 是一個對象堰氓,用來向外提供模塊接口挤渐。module 是一個對象,上面存儲了與當(dāng)前模塊相關(guān)聯(lián)的一些屬性和方法双絮。

//加載模塊
seajs.use(['myModule.js'], function(my){

});

//例如:

// 定義模塊  myModule.js
define(function(require, exports, module) {
  var $ = require('jquery.js')
  exports.add=function(){
    $('div').addClass('active');
  }
});

// 加載模塊
seajs.use(['myModule.js'], function(my){
  my.add();
});

題目3: 使用 requirejs 完善入門任務(wù)15浴麻,包括如下功能:

 1. 首屏大圖為全屏輪播
 2. 有回到頂部功能
 3. 圖片區(qū)使用瀑布流布局(圖片高度不一)得问,下部有加載更多按鈕,點擊加載更多會加載更多數(shù)據(jù)(數(shù)據(jù)在后端 mock)

代碼
預(yù)覽

筆記

1软免、CommonJS
//實際使用情況:

//math.js
exports.add = function() {
    var sum = 0, i = 0, args = arguments, l = args.length;
    while (i < l) {
        sum += args[i++];
    }
    return sum;
};
//increment.js
var add = require('math').add;
exports.increment = function(val) {
    return add(val, 1);
};
//program.js
var inc = require('increment').increment;
var a = 1;
inc(a); 
// 2
2宫纬、AMD(Require.js)
//實際使用案例:

// 定義模塊 myModule.js
define(['dependency'], function(){
    var name = 'Byron';
    function printName(){
        console.log(name);
    }

    return {
        printName: printName
    };
});

// 加載模塊
require(['myModule'], function (my){
  my.printName(); });
3、CMD(Sea.js)
//實際使用情況

// 定義模塊  myModule.js
define(function(require, exports, module) {
  var $ = require('jquery.js')
  $('div').addClass('active');
});

// 加載模塊
seajs.use(['myModule.js'], function(my){

});
//demo
//math.js
define(function(require, exports, module) {
  exports.add = function() {
    var sum = 0, i = 0, args = arguments, l = args.length;
    while (i < l) {
      sum += args[i++];
    }
    return sum;
  };
});
//increment.js
define(function(require, exports, module) {
  var add = require('math').add;
  exports.increment = function(val) {
    return add(val, 1);
  };
});
//program.js
define(function(require, exports, module) {
  var inc = require('increment').increment;
  var a = 1;
  inc(a); // 2

  module.id == "program";
});
4膏萧、AMD與CMD區(qū)別
  1. 最明顯的區(qū)別就是在模塊定義時對依賴的處理不同
    1漓骚、AMD推崇依賴前置,在定義模塊的時候就要聲明其依賴的模塊
    2向抢、CMD推崇就近依賴认境,只有在用到某個模塊的時候再去require
    3、同樣都是異步加載模塊挟鸠,AMD在加載模塊完成后就會執(zhí)行該模塊叉信,所有模塊都加載執(zhí)行完后會進入require的回調(diào)函數(shù),執(zhí)行主邏輯艘希,這樣的效果就是依賴模塊的執(zhí)行順序和書寫順序不一定一致硼身,看網(wǎng)絡(luò)速度,哪個先下載下來覆享,哪個先執(zhí)行佳遂,但是主邏輯一定在所有依賴加載完成后才執(zhí)行
    4、CMD加載完某個依賴模塊后并不執(zhí)行撒顿,只是下載而已丑罪,在所有依賴模塊加載完成后進入主邏輯,遇到require語句的時候才執(zhí)行對應(yīng)的模塊凤壁,這樣模塊的執(zhí)行順序和書寫順序是完全一致的
5吩屹、requirejs使用步驟

目的: 是代碼的模塊化,它使用了不同于傳統(tǒng)<script>標(biāo)簽的腳本加載步驟拧抖∶核眩可以用它來加速代碼加載、優(yōu)化代碼唧席,但其主要目的還是為了代碼的模塊化擦盾。

  1. 加載js文件:
<script data-main="scripts/main.js" src="scripts/require.js"></script>
//data-main屬性中的main.js文件,requirejs使用它來啟用腳本加載過程淌哟,當(dāng)頁面加載了requirejs迹卢,立即執(zhí)行main.js文件
//設(shè)置了data-main,baseUrl指向scripts目錄徒仓,也可用requirejs.config({})手動配置(當(dāng)前目錄為html所在目錄婶希,所以要以html所在目錄做為基準(zhǔn)),若兩者都沒蓬衡,baseUrl默認(rèn)指向引用requirejs的html所在的目錄喻杈。
  1. 設(shè)置main.js文件
//這是目錄表
www/
    -index.html
    -js/
    ---app/
    ------sub.js
    ---lib/
    ------jquery.js
    ------canvas.js
    ---main.js
//main.js
 requirejs.config({
    baseUrl: 'js/lib', 
    paths: {
        app: '../app'
    }
    });
    //加載模塊
    requirejs(['jquery', 'canvas', 'app/sub'],
        function   ($, canvas, sub) {
          //jquery,canvas,sub 資源都已經(jīng)加載完畢,可以用了狰晚。
    }); 
  });
//baseUrl為加載文件的起始位置筒饰,不過請注意的是paths配置(paths是路徑相對于baseUrl而言的,加載的文件都不需要.js后綴壁晒。
//想要避開baseUrl+paths(Module ID)的解析過程瓷们,直接指定加載當(dāng)前HTML頁面目錄下的腳本三種方法:
//腳本以".js"結(jié)束
//以"/"開始
//包含URL協(xié)議,如http:或https:
//canvas.js
define(['app/sub'], function(){
    var name = 'Byron';
    function printName(){
        console.log(name);
    }
    return {
        printName: printName    //這是給其他模塊的接口
    };
});
//sub.js
define(["canvas"],function(Canvas){
  Canvas.printName();            //依賴canvas模塊秒咐,并且引用模塊功能
});

(mission 4)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末谬晕,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子携取,更是在濱河造成了極大的恐慌攒钳,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件雷滋,死亡現(xiàn)場離奇詭異不撑,居然都是意外死亡,警方通過查閱死者的電腦和手機晤斩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門焕檬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人澳泵,你說我怎么就攤上這事实愚。” “怎么了兔辅?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵腊敲,是天一觀的道長。 經(jīng)常有香客問我幢妄,道長兔仰,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任蕉鸳,我火速辦了婚禮乎赴,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘潮尝。我一直安慰自己榕吼,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布勉失。 她就那樣靜靜地躺著羹蚣,像睡著了一般。 火紅的嫁衣襯著肌膚如雪乱凿。 梳的紋絲不亂的頭發(fā)上顽素,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天咽弦,我揣著相機與錄音,去河邊找鬼胁出。 笑死型型,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的全蝶。 我是一名探鬼主播闹蒜,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼抑淫!你這毒婦竟也來了绷落?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤始苇,失蹤者是張志新(化名)和其女友劉穎砌烁,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體埂蕊,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡往弓,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了蓄氧。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片函似。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖喉童,靈堂內(nèi)的尸體忽然破棺而出撇寞,到底是詐尸還是另有隱情,我是刑警寧澤堂氯,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布蔑担,位于F島的核電站,受9級特大地震影響咽白,放射性物質(zhì)發(fā)生泄漏啤握。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一晶框、第九天 我趴在偏房一處隱蔽的房頂上張望排抬。 院中可真熱鬧,春花似錦授段、人聲如沸蹲蒲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽届搁。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間卡睦,已是汗流浹背宴胧。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留么翰,地道東北人牺汤。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像浩嫌,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子补胚,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,762評論 2 345

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