簡單的說 Node.js 就是運行在服務(wù)端的 JavaScript。
Node.js模塊系統(tǒng)
為了讓Node.js的文件可以相互調(diào)用锦募,Node.js提供了一個簡單的模塊系統(tǒng)摆屯。
模塊是Node.js 應(yīng)用程序的基本組成部分,文件和模塊是一一對應(yīng)的糠亩。換言之虐骑,一個 Node.js 文件就是一個模塊,這個文件可能是JavaScript 代碼赎线、JSON 或者編譯過的C/C++ 擴展廷没。
引入模塊
在 Node.js 中狭归,引入一個模塊非常簡單亡鼠,如下我們創(chuàng)建一個 main.js 文件并引入 hello 模塊根盒,代碼如下:
var hello = require('./hello');
hello.world();
以上實例中森瘪,代碼 require('./hello') 引入了當(dāng)前目錄下的 hello.js 文件(./ 為當(dāng)前目錄,node.js 默認后綴為 js)粪躬。
Node.js 提供了 exports 和 require 兩個對象,其中 exports 是模塊公開的接口扇雕,require 用于從外部獲取一個模塊的接口,即所獲取模塊的 exports 對象凑兰。
接下來我們就來創(chuàng)建 hello.js 文件祟剔,代碼如下:
exports.world = function() {
console.log('Hello World');
}
在以上示例中组力,hello.js 通過 exports 對象把 world 作為模塊的訪問接口蛉鹿,在 main.js 中通過 require('./hello') 加載這個模塊,然后就可以直接訪 問 hello.js 中 exports 對象的成員函數(shù)了职抡。
有時候我們只是想把一個對象封裝到模塊中瞧筛,格式如下:
module.exports = function() {
// ...
}
例如:
//hello.js
function Hello() {
var name;
this.setName = function(thyName) {
name = thyName;
};
this.sayHello = function() {
console.log('Hello ' + name);
};
};
module.exports = Hello;
這樣就可以直接獲得這個對象了:
//main.js
var Hello = require('./hello');
hello = new Hello();
hello.setName('BYVoid');
hello.sayHello();
模塊接口的唯一變化是使用 module.exports = Hello 代替了exports.world = function(){}衷恭。
在外部引用該模塊時,其接口對象就是要輸出的 Hello 對象本身,而不是原先的 exports。
服務(wù)端的模塊放在哪里
使用模塊的方式:
var http = require("http");
...
http.createServer(...);
Node.js 中自帶了一個叫做 http 的模塊伍茄,我們在我們的代碼中請求它并把返回值賦給一個本地變量。
這把我們的本地變量變成了一個擁有所有 http 模塊所提供的公共方法的對象照捡。
Node.js 的 require 方法中的文件查找策略如下:
由于 Node.js 中存在 4 類模塊(原生模塊和3種文件模塊)颅湘,盡管 require 方法極其簡單,但是內(nèi)部的加載卻是十分復(fù)雜的栗精,其加載優(yōu)先級也各自不同闯参。如下圖所示:
從文件模塊緩存中加載
盡管原生模塊與文件模塊的優(yōu)先級不同,但是都會優(yōu)先從文件模塊的緩存中加載已經(jīng)存在的模塊悲立。
從原生模塊加載
原生模塊的優(yōu)先級僅次于文件模塊緩存的優(yōu)先級鹿寨。require 方法在解析文件名之后,優(yōu)先檢查模塊是否在原生模塊列表中薪夕。以http模塊為例脚草,盡管在目錄下存在一個 http/http.js/http.node/http.json 文件,require("http") 都不會從這些文件中加載寥殖,而是從原生模塊中加載玩讳。
原生模塊也有一個緩存區(qū)涩蜘,同樣也是優(yōu)先從緩存區(qū)加載嚼贡。如果緩存區(qū)沒有被加載過,則調(diào)用原生模塊的加載方式進行加載和執(zhí)行同诫。
從文件加載
當(dāng)文件模塊緩存中不存在粤策,而且不是原生模塊的時候,Node.js 會解析 require 方法傳入的參數(shù)误窖,并從文件系統(tǒng)中加載實際的文件叮盘,加載過程中的包裝和編譯細節(jié)在前一節(jié)中已經(jīng)介紹過秩贰,這里我們將詳細描述查找文件模塊的過程,其中柔吼,也有一些細節(jié)值得知曉毒费。
require方法接受以下幾種參數(shù)的傳遞:
- http、fs愈魏、path等觅玻,原生模塊。
- ./mod或../mod培漏,相對路徑的文件模塊溪厘。
- /pathtomodule/mod,絕對路徑的文件模塊牌柄。