穩定性:5 - 鎖定
1 var circle = require('./circle.js'); 2 console.log('The area of a circle of radius 4 is ' 3 + circle.area(4));
circle.js 的內容以下:node
1 var PI = Math.PI; 2 3 exports.area = function(r) { 4 return PI * r * r; 5 }; 6 7 exports.circumference = function(r) { 8 return 2 * PI * r; 9 };
模塊 circle.js 導出了函數 area() 和 circumference()。想把函數和對象添加到你的模塊的根節點,你能夠把它們添加到特殊的 exports 對象中。
模塊的局部變量是私有的,好像模塊被一個函數包裹起來同樣。在這個例子裏面,變量 PI 是 circle.js 私有的。
若是你想你的模塊的導出的根節點是一個函數(例如是一個構造函數)或者若是你想在一次指派就能導出一個完整的對象而不是每次都新建一個屬性,把它指派到 module.exports 而不是 exports 中。
在下面,bar.js 使用了一個導出一個構造函數的 square 模塊:
算法
1 var square = require('./square.js'); 2 var mySquare = square(2); 3 console.log('The area of my square is ' + mySquare.area());
square 模塊定義在 square.js 中:npm
1 // assigning to exports will not modify module, must use module.exports 2 module.exports = function(width) { 3 return { 4 area: function() { 5 return width * width; 6 } 7 }; 8 }
模塊系統的實如今 require("module") 模塊中。json
1 console.log('a starting'); 2 exports.done = false; 3 var b = require('./b.js'); 4 console.log('in a, b.done = %j', b.done); 5 exports.done = true; 6 console.log('a done');
b.js :api
1 console.log('b starting'); 2 exports.done = false; 3 var a = require('./a.js'); 4 console.log('in b, a.done = %j', a.done); 5 exports.done = true; 6 console.log('b done');
main.js :數組
1 console.log('main starting'); 2 var a = require('./a.js'); 3 var b = require('./b.js'); 4 console.log('in main, a.done=%j, b.done=%j', a.done, b.done);
當 main.js 加載 a.js,而後 a.js 轉而加載 b.js。在此時,b.js 師徒加載 a.js。爲了防止無限的循環,a.js 的 exports 對象的一個未完成的拷貝返回給 b.js 模塊。而後 b.js 完成加載,並將它的 exports 對象提供給 a.js 模塊。
當 main.js 加載完全部的模塊時,這些模塊都完成了完整的加載。程序的輸出所以將是:緩存
$ node main.js main starting a starting b starting in b, a.done = false b done in a, b.done = true a done in main, a.done= true, b.done=true
若是你在你的程序中有模塊的循環依賴,確保有依據地組織。函數
1 { "name": "some-library", 2 "main": "./lib/some-library.js" }
若是 package.json 文件在 ./some-library 文件夾中,那麼 require('./some-library') 將會嘗試加載 ./some-library/lib/some-library.js。
這是 Node 能感知 package.json 文件的程度。
若是在文件夾中沒有 package.json 文件,那麼 node 將嘗試加載 index.js 或 index.node 文件。例如,若是在上述例子中沒有 package.json 文件,那麼 require('./some-library') 將嘗試加載:ui
1 var EventEmitter = require('events').EventEmitter; 2 3 module.exports = new EventEmitter(); 4 5 // Do some work, and after some time emit 6 // the 'ready' event from the module itself. 7 setTimeout(function() { 8 module.exports.emit('ready'); 9 }, 1000);
而後在另一個文件咱們能夠
spa
1 var a = require('./a'); 2 a.on('ready', function() { 3 console.log('module a is ready'); 4 });
注意給 module.exports 賦值當即完成,不能在回調函數中完成。下面的方式不會正常工做:
x.js:
1 setTimeout(function() { 2 module.exports = {a: "hello" }; 3 }, 0);
y.js
1 var x = require('./x'); 2 console.log(x.a);
1 function require(...) { 2 // ... 3 function(module, exports) { 4 // Your module code here 5 exports = some_func; // re-assigns exports, exports is no longer 6 // a shortcut, and nothing is exported. 7 module.exports = some_func; // makes your module exports 0 8 } (module, module.exports); 9 return module; 10 }
做爲參考,若是 exports 和module.exports 之間的關係對你來講想變魔術同樣,忽略 exports 只使用 module.exports。
● id 字符串
● 返回值: 對象 解析出來的模塊的 module.exports
module.require 方法提供一個加載模塊的途徑使得就好像 require() 是在原始的模塊被調用的同樣。
注意爲了這樣作,你必須獲得一個 module 對象的引用。因爲 require() 返回 module.exports,且 module 一般只能在特定的模塊代碼裏被訪問,所以爲了使用它必須明確地導出。
● 字符串
模塊的模塊標識。典型地這是絕對路徑文件名。
require(X) from module at path Y 1. If X is a core module, a. return the core module b. STOP 2. If X begins with './' or '/' or '../' a. LOAD_AS_FILE(Y + X) b. LOAD_AS_DIRECTORY(Y + X) 3. LOAD_NODE_MODULES(X, direname(Y)) 4. THROW "not found" LOAD_AS_FILE(X) 1. If X is a file, load X as JavaScript text. STOP 2. If X.js is a file, load X.js as JavaScript text. STOP 3. If X.json is a file, parse X.json to a JavaScript Object. STOP 4. If X.node is a file, load X.node as binary addon. STOP LOAD_AS_DIRECTORY(X) 1. If X/package.json is a file a. Parse X/package.json, and look for "main" field. b. let M = X + (json main field) c. LOAD_AS_FILE(M) 2. If X/index.js is a file, load X/index.js as JavaScript text. STOP 3. If X/index.node is a file, load X/index.node as binary addon. STOP LOAD_NODE_MODULES(X, START) 1. let DIRS=NODE_MODULES_PATHS(START) 2. for each DIR in DIRS: a. LOAD_AS_FILE(DIR/X) b. LOAD_AS_DIRECTORY(DIR/X) NODE_MODULES_PATHS(START) 1. let PARTS = path split(START) 2. let ROOT = index of first instance of "node_modules" in PARTS, or 0 3. let I = count of PARTS -1 4. let DIRS = [] 5. while I > ROOT a. if PARTS[I] = "node_modules" CONTINUE b. DIR = path join(PARTS[0 .. I] + "node_modules") c. let I = I - 1 6. return DIRS
1 require.main === module
對應文件 foo.js,若是經過 node foo.js 運行該值將是 true,但若是經過 require('./foo') 運行給支將是 false。
由於 module 提供了一個 filename 屬性(一般和 __filename相等),當前應用程序的入口點能夠經過檢查 require.main.filename 獲得。