define('alpha' ,['require', "exports", "module"], function(require, exports, module) { var foo = require('foo'); module.exports = exports = function() { foo.doSomething(); } });
參數node
第一個是要定義的模塊名字(id)
第二個是要用到的模塊名,其實更專業點講是定義的這個模塊所依賴的模塊名稱
第三個回調函數,是要定義模塊內容app
分析方法:替換部分代碼進行分析模塊化
先來把回調中的require,exports,module替換了看看。函數
function callback(exports, module) { // 假設foo是最簡單的對象,把require('foo')換成最簡答的對象看看 var foo = { 'doSomething': function() {} }; module.exports = exports = function() { foo.doSomething(); } }
那麼其實已經不難看出,require其實就至關因而個查詢函數吧,我給他傳個對象名,它就能給我一個具體的對象。優化
var require = function(name) { var modules = {'foo': {'doSomething': function() {}}}; return modules[name] || {}; }
那麼整個代碼能夠換成ui
var require = function(name) { var modules = {'foo': {'doSomething': function() {}}}; return modules[name] || {}; } function callback(exports, module) { var foo = require('foo'); module.exports = exports = function() { foo.doSomething(); } }
看起來好像有點道理哦,等會兒,等會兒,這裏的modules又從哪兒冒出來的,哈哈哈,被發現了,別急慢慢來code
在替換以前,先來了解下exports和module.exports這兩貨是幹啥的,而要了解他們先來看看模塊是啥。對象
其實模塊麼,簡單來講就是一個高級別的function,輸入,處理,輸出。至於爲啥js的模塊化爲啥這麼困難,這個問題不是三言兩語就能解釋清楚的,就不展開了(其實真實狀況是,我也不清楚,哈哈哈)內存
既然模塊要作輸出,那麼輸出什麼東西總要知道吧,而module.exports的做用就是這個,存儲模塊輸出的內容。get
也就是說,這個模塊中要給外部使用的東西全放在module.exports裏頭了。廢話真多,是的哈- -.
而要說清exports和module.exports的二三事,又不是件容易的事,簡單理解,exports和module.exports指向同一內存區域。有興趣能夠看看exports 和 module.exports 的區別。
那來改造一下,把module.exports,exports也提煉出來看看
var require = function(name) { var modules = {'foo': {'doSomething': function() {}}}; return modules[name] || {}; } var module = {}; var module.exports = exports = {}; function callback() { var foo = require('foo'); module.exports = exports = function() { foo.doSomething(); } }
// 這裏的id至關於模塊名,deps就是須要依賴的模塊名稱列表 define = function(id , deps, callback) { callback(require, exports, module); };
暈,那require,exports,module跑哪兒溜達去了?加上去看看
define = function(id , deps, callback) { var require = function(name) { var modules = {'foo': {'doSomething': function() {}}}; return modules[name] || {}; } var module = {}; var module.exports = exports = {}; callback(require, exports, module); };
看上去挺有道理的麼,那麼modules這玩意兒究竟是哪兒冒出來的呢。
能夠看出來modules 裏面存放着的是foo模塊的內容,那這些內容是怎麼來的呢?經過foo的module.exports提供的啊。那麼modules裏面其實放的是,foo的module.exports。
而foo對於當前模塊來講是外部的模塊。而我想調用外面的東西,只有兩種辦法,要麼傳參數,要麼經過全局變量(不過或許大神還有其餘方案,我就只曉得這兩種了)。define裏面有的參數沒有一個是存放module.exports的。那麼答案呼之欲出了,modules是全局變量。
modules = {}; function load(id, exports) { (modules || (modules = {}))[id] = exports; }
再來看看完整的代碼,變成啥樣了
modules = {}; function load(name, exports) { (modules || (modules = {}))[name] = exports; } define = function(id, deps, callback) { var require = function(name) { return modules[name] || {}; } var module = {}; var module.exports = exports = {}; callback(require, exports, module); load(id, module.exports); };
到如今差很少已經成型了,那麼這裏的require, exports, module都是外來的模塊吧bingo,其實callback裏的模塊都是根據deps來的,去掉require, exports, module
modules = {}; function load(name, exports) { (modules || (modules = {}))[name] = exports; } define = function(id, deps, callback) { // 至關於 // var module = {}; // var module.exports = {}; var module = modules['module']; // 至關於 //var require = function(name) { // return modules[name] || {}; //} var require = modules['require']; var args = deps.map(require); callback.apply(null, args); load(id, module.exports); };
define('alpha' ,['foo'], function(foo) { return function() { foo.doSomething(); } });
咦,精簡了很多誒。沒有exports了誒,會返回了麼
modules = {}; function load(name, exports) { (modules || (modules = {}))[name] = exports; } define = function(id, deps, callback) { var module = modules['module']; var require = modules['require']; var args = deps.map(require); var exports = callback.apply(null, args); load(id, exports || module.exports); };
OK,先告一段落了,累死我丫了。在慢慢優化吧,唉。
exports 和 module.exports 的區別這篇文章很不賴。
人家大神已經說得很是好了。我在了淺薄的打個比方,我有個文件夾叫module.exports,而後我建立了一個超連接叫exports,那我在任何一個裏面操做最終都會反應到另外一個裏,但若是我把超連接exports刪了把它的指向地址改了,並不會影響真正的文件夾module.exports。
而有不少人明明已經改了超連接exports的指向地址(如:exports = 123;),再在超連接裏面作了不少操做(如:exports.hello = 456;),那都不會對真正的文件夾module.exports起到任何做用(你是見不到module.exports.hello === 456的)。