當(dāng)一個(gè)網(wǎng)站復(fù)雜度較高需要多人協(xié)作開發(fā)時(shí),傳統(tǒng)的非模塊化編程模式容易導(dǎo)致代碼沖突和依賴等問題,而模塊化編程的誕生正是為了解決此類問題。然而,在ES6之前,原生JavaScript是不支持模塊化的,因此就出現(xiàn)了一系列的JavaScript庫(kù)來實(shí)現(xiàn)此功能,這些庫(kù)主要遵循以下三種規(guī)范:
① CommonJS
② AMD
③ CMD
接下來我就粗略地講講這三種規(guī)范。
一、CommonJS規(guī)范
關(guān)鍵詞: module,exports,require
CommonJS規(guī)范下的模塊調(diào)用是同步的,也就是說必須等模塊加載完成之后,接下來的代碼才能繼續(xù)運(yùn)行。因此,該規(guī)范主要適用于服務(wù)端,因?yàn)榉?wù)端可以直接從硬盤中調(diào)用所需要的模塊,而這個(gè)過程速度是非??斓?。相比之下,通過網(wǎng)絡(luò)調(diào)用所需模塊的瀏覽器客戶端則不適合使用該規(guī)范。
目前使用該規(guī)范的典型代表有:Node.js、微信小程序。
下面以Node.js中的兩個(gè)小例子,簡(jiǎn)單講講CommonJS規(guī)范下的模塊化編程。
1. 無返回值的模塊調(diào)用
//module.js
console.log('這是一個(gè)模塊。');
//main.js
require('./module'); // 或?qū)懗?require('./module.js'),但千萬注意不能寫成 require('module')
以上module.js和main.js兩個(gè)文件處于同一目錄下。
2. 有返回值的模塊調(diào)用
//module.js
function foo(){
console.log('這是一個(gè)模塊。');
}
module.exports = { // 此處提供模塊對(duì)外接口
foo: foo // 此處對(duì)外接口中的方法名不一定要與以上定義的方法名一致,比如可以寫成 func: foo,那么此時(shí)調(diào)用時(shí)就應(yīng)該寫成 module.func()
};
//main.js
var module = require('./module.js'); // 加載module模塊
module.foo(); // 此處調(diào)用module模塊下的foo方法,該方法名須與模塊中對(duì)外接口方法名一致
二、AMD規(guī)范
關(guān)鍵詞: define,require
與CommonJS不同,AMD規(guī)范下的模塊調(diào)用是異步的,主要適用于瀏覽器客戶端。
目前使用該規(guī)范的典型代表有:require.js、curl.js。
下面以require.js為例,簡(jiǎn)單講講AMD規(guī)范下的模塊化編程。
<!--HTML-->
<script src="scripts/require.js"></script>
<script src="scripts/main.js" data-main="scripts/main"></script>
1. 無返回值的模塊調(diào)用
//module.js
console.log('這是一個(gè)模塊。');
//main.js
require(['scripts/module']); // 請(qǐng)求的模塊路徑用數(shù)組表示
2. 有返回值的模塊調(diào)用
//module.js
function foo(){
console.log('這是一個(gè)模塊。');
}
define(function(){
return {
foo: foo
}
});
//main.js
require(['scripts/module'],function(module){
module.foo();
});
三、CMD規(guī)范
關(guān)鍵詞: use,define,require,exports,module
CMD規(guī)范結(jié)合了以上兩種規(guī)范的特點(diǎn),既可以同步調(diào)用,也可以異步調(diào)用,在語法上也非常相似。
目前使用該規(guī)范的典型代表有:sea.js。
下面就以sea.js為例,簡(jiǎn)單講講CMD規(guī)范下的模塊化編程。
<!--HTML-->
<script src="scripts/sea.js"></script>
<!--引入主模塊,模塊根目錄為sea.js所在目錄,有點(diǎn)類似于C語言中的main函數(shù)-->
<script type="text/javascript">
seajs.use('main');
</script>
1. 無返回值的模塊調(diào)用
//module.js
console.log('這是一個(gè)模塊。');
//main.js
define(function(require,exports,module){
require('module');
});
這里需要重點(diǎn)說明一下,define()中回調(diào)函數(shù)中所傳參數(shù)名稱不允許修改。
2. 有返回值的模塊調(diào)用
定義模塊:
//module.js
function foo(){
console.log('這是一個(gè)模塊。');
}
define(function(require,exports,module){
//也可以直接通過return方式暴露模塊接口,這樣就與AMD規(guī)范相同
module.exports = {
foo: foo
}
});
調(diào)用模塊存在同步和異步兩種方式:
① 同步調(diào)用
//main.js
define(function(require,exports,module){
var module = require('module');
module.foo();
});
② 異步調(diào)用
//main.js
define(function(require,exports,module){
require.async('module',function(module){
module.foo();
});
});
本次有關(guān)JavaScript模塊化編程規(guī)范的分享就到這里,若有不到之處,歡迎指正,謝謝!