var math = require('math');
[!NOTE]
上下文提供exports對象用於導出當前模塊的方法和變量,而且他是惟一的導出出口前端
exports其實是module.exports,而module.exports就是以一個暴露給外部的對象。node
// a.js module.exports = { a: 1 } // or exports.a = 1 // b.js var module = require('./a.js') module.a // -> log 1
var module = require('./a.js') module.a // 這裏其實就是包裝了一層當即執行函數,這樣就不會污染全局變量了, // 重要的是 module 這裏,module 是 Node 獨有的一個變量 module.exports = { a: 1 } // module 基本實現 var module = { id: 'xxxx', // 我總得知道怎麼去找到他吧 exports: {} // exports 就是個空對象 } // 這個是爲何 exports 和 module.exports 用法類似的緣由 var exports = module.exports var load = function (module) { // 導出的東西 var a = 1 module.exports = a return module.exports }; // 而後當我 require 的時候去找到獨特的 // id,而後將要使用的東西用當即執行函數包裝下,over
在Node中引入模塊,須要經歷3個步驟json
在node中,模塊分爲兩類:一類是node提供的模塊稱爲核心模塊,一類是用戶編寫的成爲文件模塊。後端
核心模塊在編譯中編譯成了二進制文件。在Node進程啓動時,部分核心模塊就被直接加載入內存。因此這部分核心模塊引入時就省了文件定位和編譯執行這兩個步驟,而且在路徑分析中優先判斷,它的加載速度是最快的。緩存
文件模塊是運行時動態加載。須要完整的路徑分析、文件定位、編譯執行網絡
Node對引入的模塊都回進行緩存,並且緩存的是編譯執行後的對象。異步
不論是核心模塊仍是文件模塊,require()都一概採用緩存優先的方式。函數
[!NOTE]
每個編譯成功的模塊都會將其文件路徑索引緩存在Module._cache對象上,以提升二次引入性能性能
[!NOTE]
在編譯的過程當中,Node對獲取的JS文件進行了頭尾包裝。這也是每一個模塊都能訪問到 require、exports、module、__filename、__dirname的緣由ui
(funciton(exports, require, module, __filename, __dirname) { /* 本身寫的代碼 */ });
這樣使得模塊文件間都進行了做用域隔離,不用擔憂變量污染全局。
爲moudle.exports賦值,exports對象是經過形參的方式傳入,直接賦值形參會改變形參的引用,但並不能改變做用域外的值。
exports = function() { // my class } var change = function(a) { a = 100; } var a = 10; change(a); console.log(a); // => 10
若是要達到require引入一個類的效果,請賦值給 module.exports對象。這個迂迴的方案不改變形參的引用。
Node調用process.dlopen()方法進行加載和執行。
實際上 .node模塊並不須要編譯,由於它是編寫C/C++模塊以後編譯生成的,因此這裏只有加載和執行的過程。在執行的過程當中,模塊exports對象與.node模塊產生練習,而後返回給調用者。
[!NOTE]
Node的核心模塊在編譯成可執行文件的過程當中被編譯進了二進制文件。核心模塊其實分爲C/C++編寫的和Javascript編寫的兩部分,其中C/C++文件存放在Node項目的src目錄下,Javascript文件存放在lib目錄下。
C/C++拓展模塊
模塊調用棧
先後端公用模塊
前端瓶頸在於帶寬,後端瓶頸在於CPU和內存等資源。前端須要經過網絡加載代碼,後端則從磁盤加載,兩者加載速度再也不同一量級上。
node的模塊引入幾乎都是同步的,但前端模塊如果也採用同步方式來引入必會在用戶體驗上形成很大的問題,即UI初始化實際過長
Asynchronous Moudle Definition 「異步模塊定義」, AMD須要在聲明的時候指定全部的依賴,經過形參傳遞依賴到模塊內容中。
定義以下
define(id?, dependencies, factory);
與AMD主要區別在於定於模塊與依賴引入部分。
CMD支持動態引入
define(funtion(require, exports, moudle) { // The module code goes here })