node.js module初步理解

轉(zhuǎn)載地址:http://www.cnblogs.com/dolphinX/p/3485260.html

在開(kāi)發(fā)一個(gè)復(fù)雜的應(yīng)用程序的時(shí)候,我們需要把各個(gè)功能拆分嘁字、封裝到不同的文件夫椭,在需要的時(shí)候引用該文件掸掸。沒(méi)人會(huì)寫一個(gè)幾萬(wàn)行代碼的文件,這樣在可讀性蹭秋、復(fù)用性和維護(hù)性上都很差扰付,幾乎所有的編程語(yǔ)言都有自己的模塊組織方式,比如Java中的包感凤、C#中的程序集等悯周,node.js使用模塊和包來(lái)組織,其機(jī)制實(shí)現(xiàn)參照了CommonJS標(biāo)準(zhǔn)陪竿,雖未完全遵守禽翼,但差距不大屠橄,使用起來(lái)非常簡(jiǎn)單。
什么是模塊
在node.js中模塊與文件是一一對(duì)應(yīng)的闰挡,也就是說(shuō)一個(gè)node.js文件就是一個(gè)模塊锐墙,文件內(nèi)容可能是我們封裝好的一些JavaScript方法、JSON數(shù)據(jù)长酗、編譯過(guò)的C/C++拓展等溪北,在關(guān)于node.js的誤會(huì)提到過(guò)node.js的架構(gòu)


其中http、fs夺脾、net等都是node.js提供的核心模塊之拨,使用C/C++實(shí)現(xiàn),外部用JavaScript封裝咧叭。
創(chuàng)建蚀乔、加載模塊
模塊在node.js中的概念很簡(jiǎn)單,看看如何創(chuàng)建一個(gè)我們自己的模塊供開(kāi)發(fā)復(fù)用菲茬。
在node.js中創(chuàng)建模塊非常簡(jiǎn)單吉挣,一個(gè)文件就是一個(gè)模塊,所以我們創(chuàng)建一個(gè)test.js文件就創(chuàng)建了一個(gè)模塊
test.js

var name='';

function setName(n){
    name=n;
} 

function printName(){
    console.log(name);
}

問(wèn)題是怎么使外部訪問(wèn)這個(gè)module婉弹,我們知道客戶端的JavaScript使用script標(biāo)簽引入JavaScript文件就可以訪問(wèn)其內(nèi)容了睬魂,但這樣帶了的弊端很多,最大的就是作用域相同镀赌,產(chǎn)生沖突問(wèn)題氯哮,以至于前端大師們想出了立即執(zhí)行函數(shù)等方式,利用閉包解決佩脊。node.js使用exports和require對(duì)象來(lái)解決對(duì)外提供接口和引用模塊的問(wèn)題蛙粘。
我們可以把模塊中希望被外界訪問(wèn)的內(nèi)容定義到exports對(duì)象中,對(duì)test.js稍作修改就可以了
test.js

var name='';

function setName(n){
    name=n;
} 

function printName(){
    console.log(name);
}

exports.setName=setName;
exports.printName=printName;

這樣我們?cè)谙嗤窂较聞?chuàng)建index.js威彰,使用require引用一下test.js module
index.js

var test=require('./test');

test.setName('Byron');
test.printName();

exports一個(gè)對(duì)象
有時(shí)候我們希望模塊對(duì)外提供的使一個(gè)對(duì)象出牧,修改一下test.js
test.js

var Student=function(){
    var name='';

     this.setName=function(n){
        name=n;
    }; 

    this.printName=function(){
        console.log(name)    ;
    };
};

exports.Student=Student;
這樣我們對(duì)外提供了一個(gè)Student類,在使用的時(shí)候需要這樣

var Student=require('./test').Student;
var student=new Student();
student.setName('Byron');
student.printName();

這樣我們的require語(yǔ)句就可以優(yōu)雅一些了

var Student=function(){
    var name='';

     this.setName=function(n){
        name=n;
    }; 

    this.printName=function(){
        console.log(name)    ;
    };
};

module.exports=Student;

很神奇的樣子歇盼,不是說(shuō)好的exports是模塊公開(kāi)的接口嘛舔痕,那么module.exports是什么東西?
module.exports與exports
事實(shí)的情況是醬紫的豹缀,其實(shí)module.exports才是模塊公開(kāi)的接口伯复,每個(gè)模塊都會(huì)自動(dòng)創(chuàng)建一個(gè)module對(duì)象,對(duì)象有一個(gè)modules的屬性邢笙,初始值是個(gè)空對(duì)象{}啸如,module的公開(kāi)接口就是這個(gè)屬性——module.exports。既然如此那和exports對(duì)象有毛線關(guān)系暗摺叮雳!為什么我們也可以通過(guò)exports對(duì)象來(lái)公開(kāi)接口呢想暗?
為了方便,模塊中會(huì)有一個(gè)exports對(duì)象帘不,和module.exports指向同一個(gè)變量说莫,所以我們修改exports對(duì)象的時(shí)候也會(huì)修改module.exports對(duì)象,這樣我們就明白網(wǎng)上盛傳的module.exports對(duì)象不為空的時(shí)候exports對(duì)象就自動(dòng)忽略是怎么回事兒了寞焙,因?yàn)閙odule.exports通過(guò)賦值方式已經(jīng)和exports對(duì)象指向的變量不同了储狭,exports對(duì)象怎么改和module.exports對(duì)象沒(méi)關(guān)系了。
大概就是這么過(guò)程

module.exports=exports={};
......

module.exports=new Object();

exports=xxx;//和new Object沒(méi)有關(guān)系了捣郊,最后返回module.exports辽狈,所以改動(dòng)都無(wú)效了

一次加載
無(wú)論調(diào)用多少次require,對(duì)于同一模塊node.js只會(huì)加載一次呛牲,引用多次獲取的仍是相同的實(shí)例稻艰,看個(gè)例子
test.js

var name='';

function setName(n){
    name=n;
} 

function printName(){
    console.log(name);
}

exports.setName=setName;
exports.printName=printName;

index.js

 var test1=require('./test'),
    test2=require('./test');

test1.setName('Byron');
test2.printName();

執(zhí)行結(jié)果并不是'',而是輸出了test1設(shè)置的名字侈净,雖然引用兩次,但是獲取的是一個(gè)實(shí)例
require搜索module方式
node.js中模塊有兩種類型:核心模塊和文件模塊僧凤,核心模塊直接使用名稱獲取畜侦,比如最長(zhǎng)用的http模塊

var http=require('http');

在上面例子中我們使用了相對(duì)路徑 './test'來(lái)獲取自定義文件模塊,那么node.js有幾種搜索加載模塊方式呢躯保?
核心模塊優(yōu)先級(jí)最高旋膳,直接使用名字加載,在有命名沖突的時(shí)候首先加載核心模塊
文件模塊只能按照路徑加載(可以省略默認(rèn)的.js拓展名途事,不是的話需要顯示聲明書寫)絕對(duì)路徑
相對(duì)路徑

查找node_modules目錄验懊,我們知道在調(diào)用 npm install <name> 命令的時(shí)候會(huì)在當(dāng)前目錄下創(chuàng)建node_module目錄(如果不存在) 安裝模塊,當(dāng) require 遇到一個(gè)既不是核心模塊,又不是以路徑形式表示的模塊名稱時(shí),會(huì)試圖 在當(dāng)前目錄下的 node_modules 目錄中來(lái)查找是不是有這樣一個(gè)模塊尸变。如果沒(méi)有找到,則會(huì) 在當(dāng)前目錄的上一層中的 node_modules 目錄中繼續(xù)查找,反復(fù)執(zhí)行這一過(guò)程,直到遇到根 目錄為止义图。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市召烂,隨后出現(xiàn)的幾起案子碱工,更是在濱河造成了極大的恐慌,老刑警劉巖奏夫,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件怕篷,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡酗昼,警方通過(guò)查閱死者的電腦和手機(jī)廊谓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)麻削,“玉大人蒸痹,你說(shuō)我怎么就攤上這事春弥。” “怎么了电抚?”我有些...
    開(kāi)封第一講書人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵惕稻,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我蝙叛,道長(zhǎng)俺祠,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任借帘,我火速辦了婚禮蜘渣,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘肺然。我一直安慰自己蔫缸,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布际起。 她就那樣靜靜地躺著拾碌,像睡著了一般。 火紅的嫁衣襯著肌膚如雪街望。 梳的紋絲不亂的頭發(fā)上校翔,一...
    開(kāi)封第一講書人閱讀 49,144評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音灾前,去河邊找鬼防症。 笑死,一個(gè)胖子當(dāng)著我的面吹牛哎甲,可吹牛的內(nèi)容都是我干的蔫敲。 我是一名探鬼主播,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼炭玫,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼奈嘿!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起吞加,我...
    開(kāi)封第一講書人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤指么,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后榴鼎,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體伯诬,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年巫财,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了盗似。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡平项,死狀恐怖赫舒,靈堂內(nèi)的尸體忽然破棺而出悍及,到底是詐尸還是另有隱情,我是刑警寧澤接癌,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布心赶,位于F島的核電站,受9級(jí)特大地震影響缺猛,放射性物質(zhì)發(fā)生泄漏缨叫。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一荔燎、第九天 我趴在偏房一處隱蔽的房頂上張望耻姥。 院中可真熱鬧,春花似錦有咨、人聲如沸琐簇。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)婉商。三九已至,卻和暖如春渣叛,著一層夾襖步出監(jiān)牢的瞬間据某,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工诗箍, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人挽唉。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓滤祖,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親瓶籽。 傳聞我的和親對(duì)象是個(gè)殘疾皇子匠童,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • Node.js是目前非常火熱的技術(shù)塑顺,但是它的誕生經(jīng)歷卻很奇特汤求。 眾所周知,在Netscape設(shè)計(jì)出JavaScri...
    w_zhuan閱讀 3,609評(píng)論 2 41
  • topics: 1.The Node.js philosophy 2.The reactor pattern 3....
    宮若石閱讀 1,059評(píng)論 0 1
  • 1 Node.js模塊的實(shí)現(xiàn) 之前在網(wǎng)上查閱了許多介紹Node.js的文章,可惜對(duì)于Node.js的模塊機(jī)制大都著...
    zlx_2017閱讀 1,221評(píng)論 0 1
  • 1 Node.js模塊的實(shí)現(xiàn)# 之前在網(wǎng)上查閱了許多介紹Node.js的文章,可惜對(duì)于Node.js的模塊機(jī)制大都...
    七寸知架構(gòu)閱讀 2,053評(píng)論 1 50
  • Node.js是目前非逞暇埽火熱的技術(shù)扬绪,但是它的誕生經(jīng)歷卻很奇特。 眾所周知裤唠,在Netscape設(shè)計(jì)出JavaScri...
    Myselfyan閱讀 4,064評(píng)論 2 58