模塊化開發(fā)概念
把JS文件劃分開,避免全部冗余在一起
為什么需要模塊化開發(fā)?
- 使文件更加清晰
- 模塊之間的可以互相引用
- html中引入JS更加方便快捷
AMD、CMD、CommonJS規(guī)范介紹
-
AMD是RequireJS在推廣過程中對模塊定義的規(guī)范化產(chǎn)出
Asynchomous Module Definition(異步模塊定義)
CMD是Sea.JS在推廣過程中對模塊定義的規(guī)范化產(chǎn)出
-
CommonJS是NodeJS使用的一種模塊化方式
?
RequireJS
require.js是一個JavaScript文件和模塊載入器
實(shí)現(xiàn)了JS文件的異步加載,避免網(wǎng)頁失去響應(yīng)
-
管理模塊之間的依賴性,便于代碼的編寫與維護(hù)
?
RequireJS流程簡述
- 使用requirejs時,會把所有的js都交給requirejs來管理,把data-main指向main.js
- 通過在main.js里面定義的require方法或者define方法,requirejs會把這些依賴和回調(diào)方法用一個數(shù)據(jù)結(jié)構(gòu)保存起來
- 當(dāng)頁面加載時,requirejs會根據(jù)這些依賴預(yù)先把需要的js通過document.createElement的方法引入到DOM中
- 由于依賴的JS也是按照requirejs的規(guī)范來寫的,所以他們也會有define或者require方法,同意類似的第二步這樣循環(huán)向上查找依賴,同樣進(jìn)行保存
- 當(dāng)js里需要用到依賴所返回的結(jié)果時(通常是一個鍵值對對象),requirejs便會把之前那個保存回調(diào)方法的數(shù)據(jù)結(jié)構(gòu)里面的方法拿出來并且運(yùn)行,然后把結(jié)果給需要依賴的方法
特殊說明:本身依賴的模塊會比本身先加載
RequireJS基本使用
異步加載
異步加載requirejs文件
async="true"屬性表明需要異步加載當(dāng)前文件,由于IE不支持這個屬性,需要添加defer
<script src="js/requirejs-2.2.0.js" async="true" defer charset="utf-8"></script>
同步加載,時間固定,按照代碼的位置來。如果是異步加載,加載的時間不固定。
配置主模塊
使用data-main屬性設(shè)置主模塊
require.js默認(rèn)文件名后綴為js,所以不需要添加后綴
<script src="js/requirejs-2.2.0.js" data-main="app" charset="utf-8"></script>
app.js
變量名 require 和 requirejs完全一致
-
baseUrl:配置公共路徑 -
paths:路徑和名稱的映射關(guān)系 -
shim:解決模塊不支持requirejs和前置依賴等其它問題
requirejs.config({
baseUrl: './js', // 公共路徑
paths: { // 給路徑起名
jquery: 'jquery-2.2.3',
baiduTemplate: 'baiduTemplate',
zepto: 'zepto/zepto',
'zepto.event': 'zepto/src/event',
'zepto.ajax': 'zepto/src/ajax',
},
shim: { // 對模塊的特殊處理
baiduTemplate: { // baiduTemplate默認(rèn)不支持requirejs,需要配置
exports: 'baidu.template' // 導(dǎo)出對應(yīng)的對象
},
zepto: { // zepto默認(rèn)不支持requirejs,需要配置
exports: '$' // 導(dǎo)出$對象,方便外部使用
},
'zepto.event': { // event模塊為
deps: ['zepto']
},
'zepto.ajax': {
deps: ['zepto']
}
}
});
引入模塊
requirejs(['baiduTemplate', 'zepto'], function (baiduTemplate, $) {
$('h2').css('color', 'red');
$('h2').on('click', function () {
console.log('單擊事件');
});
$.get('http://www.vrserver.applinzi.com/aixianfeng/apihome.php', function (data) {
// 使用模板生成數(shù)據(jù),并拼接到頁面中
var html = baiduTemplate('menu', {menu: data.data.menu})
$('header').html(html);
}, 'json');
});
定義模塊
define(['jquery'], function ($) {
return {
changeColor: function () {
$('header').css('color', 'pink');
}
}
});
模塊名稱的問題
命名模塊 | 匿名模塊
jQuery源碼,Line:9806
if ( typeof define === "function" && define.amd ) {
define( "jquery", [], function() {
return jQuery;
} );
}
使用RequireJS定義模塊的時候,define()函數(shù)有三個參數(shù):
- 參數(shù)一,字符串,代表模塊的名稱,如果填寫了,則必須使用
- 參數(shù)二,當(dāng)前模塊所依賴的其它模塊
- 參數(shù)三,回調(diào)函數(shù),參數(shù)為依賴的模塊對應(yīng)的映射