1.原始模塊系統(tǒng):
最原始的文件加載方式。如果把每個文件都看做是一個模塊,那么通常他們是暴露在全局作用域下,也就是window對象中。不同的模塊接口調(diào)用的都是同一個作用域。
這些原始的加載方法暴露了一些弊端:
》全局作用域下造成的變量沖突
》文件只能按照<script></script>順序加載
》開發(fā)人員必須主觀的解決模塊和代碼庫的依賴關(guān)系
》在大型項(xiàng)目中,各種資源難以管理,長期積累問題導(dǎo)致代碼庫混亂不堪
2.CommonJs:
服務(wù)端的Node.js遵循common.js規(guī)范、該規(guī)范的核心思想史允許模塊通過require方法來同步加載索要依賴的其他模塊。然后通過exports或module.exports 來導(dǎo)出需要暴露的接口
舉個栗子:
// example.js
var x = 5;
var addX = function (value) {
return value + x;
};
module.exports.x = x;
module.exports.addX = addX;
var example = require('./example.js');
console.log(example.x); //5
console.log(example.addX(1)); //6
優(yōu)點(diǎn):所有代碼都運(yùn)行在模塊作用域。不會污染全局作用域
模塊可以多次加載,但只會在第一次加載時,運(yùn)行一次,然后運(yùn)行結(jié)果就被緩存了
缺點(diǎn):同步模塊加載不適用于瀏覽器環(huán)境。意味著阻塞加載。瀏覽器資源是異步加載的。
不能非阻塞的并行加載多個模塊
3.AMD: 異步模塊定義 --- (Require.js)
(Asynchronous Module Definition)
AMD是Require.js在推廣過程中對模塊定義的規(guī)范化產(chǎn)出。
https://github.com/amdjs/amdjs-api/wiki/AMD-(%E4%B8%AD%E6%96%87%E7%89%88)
AMD也采用require()語句加載模塊,但是他有兩個參數(shù)
//define(id?,dependencies?,fatory)
define("module", ["dep1", "dep2"], function(d1, d2) {
return someExportedValue;
});
//require([module],callback);
require(["module", "../file"], function(module, file) { /* ... */ });
優(yōu)點(diǎn):
適合在瀏覽器環(huán)境中異步加載模塊
可以并行加載多個模塊
缺點(diǎn):
提高了開發(fā)成本,代碼的閱讀和書寫比較困難,模塊定義方式的語義不順暢
不符合通用的模塊化思維方式,是一種妥協(xié)的實(shí)現(xiàn)
關(guān)于cmd和amd的區(qū)別參考:https://www.zhihu.com/question/20351507/answer/14859415
https://www.douban.com/note/283566440/
4.CMD:通用模塊定義--- (sea.js)
define(function(require, exports, module) {
var $ = require('jquery');
var Spinning = require('./spinning');
exports.doSomething = ...
module.exports = ...
})