node.js - 基礎之module

nodejs-exports.jpg

1. node.js模塊概述

為了讓node.js的文件可以相互調用汤善,node.js提供了一個簡單的模塊系統(tǒng)。模塊是node.js應用程序基本的組成部分票彪,文件和模塊是一一對應的红淡。換言之,一個node.js文件就是一個模塊降铸,這個文件可能是javascript代碼在旱、json或者編譯過的c/c++擴展。

其中http推掸、fs桶蝎、net等都是node.js提供的核心模塊驻仅,使用c/c++實現,外部用javascript封裝登渣。

2. 創(chuàng)建模塊的兩種方式

創(chuàng)建模塊有兩種方式噪服,

  • 通過exports創(chuàng)建
  • 通過module.exports創(chuàng)建

2.1 通過exports創(chuàng)建模塊

node.js中,創(chuàng)建一個模塊非常簡單胜茧,我們創(chuàng)建一個main.js文件粘优,它引用了hello模塊,代碼如下呻顽,

var hello = require('./hello')
hello.world()

在上面的代碼中雹顺,require('./hello')引入了當前目錄下的hello.js文件。

./代表當前目錄廊遍,node.js默認后綴為js嬉愧。

node.js提供了exportsrequire兩個對象,其中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對象的成員函數了。

2.2 通過module.exports創(chuàng)建模塊

有時候我們只是想把一個對象封裝到模塊中论颅,如下格式哎垦,

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代碼今妄,

// main.js
var Hello = require('./hello')
hello = new Hello()
hello.setName('BYVoid')
hello.sayHello()

模塊接口的唯一變化是使用module.exports = Hello代替了exports.world = function() {}郑口。在外部引用該模塊時,其接口對象就是要輸出的Hello對象本身盾鳞,而不是原先的exports犬性。

2.3 exports和module.exports區(qū)別

為了更好地解釋exports和module.exports之間的關系,先通過一個簡單的js示例來做一個說明腾仅,如下代碼乒裆,

var a = {name: 1}
var b = a

console.log(a)
console.log(b)

b.name = 2
console.log(a)
console.log(b)

b = {name: 3}
console.log(a)
console.log(b)

運行test.js結果為,

{ name: 1 }
{ name: 1 }
{ name: 2 }
{ name: 2 }
{ name: 2 }
{ name: 3 }

簡單解釋一下上面的代碼:a是一個對象推励,b是對a對象的引用鹤耍,此時a和b只想同一塊內存肉迫,所以前兩個輸出一樣;當對b做修改時稿黄,則a和b只想同一塊內存地址的內容發(fā)生了改變喊衫,所以a的值改變也體現了出來;當b被覆蓋時杆怕,b只想了一塊新的內存格侯,而a還是只想原來的內存,所以最后兩個輸出不一樣财著。

明白了上面的例子之后,只需要指點3點就能了解exports和module.exports的區(qū)別了撑碴,

  1. module.exports初始值為一個空對象{}
  2. exports是只想module.exports的引用
  3. require()返回的是module.exports而不是exports

也就是說撑教,module.exports才是真正的接口,exports只不過是它的一個輔助工具醉拓。最攻返回給調用者的是module.exports而不是exports伟姐。

再強調一點,在node.js中亿卤,一個文件對應一個模塊愤兵。為了方便,模塊中會有一個exports對象排吴,它和module.exports指向同一個變量秆乳,所以我們修改exports對象的時候也會修改module.exports對象;當我們通過賦值方式為module.exports賦值時候钻哩,此時module.exports與exports對象指向的變量就不同了屹堰,所以無論exports對象怎么改,都和module.exports對象沒有任何關系了街氢。

加粗扯键!加粗!加粗珊肃!一般來說荣刑,推薦使用module.exports,盡量少使用exports伦乔。

3. require搜索module的方式

在node.js中模塊有兩種類型厉亏,即,

  • 核心模塊
  • 文件模塊

3.1 搜索核心模塊

核心模塊直接使用名稱獲取烈和,例如經常使用的http模塊叶堆,使用如下代碼獲取,

var http = require('http')
...
http.createServer()

簡要描述一下上面的代碼斥杜,node.js中自帶了一個叫做http的模塊虱颗,在上述代碼中我們請求它并把返回的值賦值給一個本地變量沥匈,這樣本地變量就編程了一個擁有所有http模塊所提供的公共方法的對象。

3.2 搜索文件模塊

在前面創(chuàng)建模塊的demo中忘渔,通過require('./hello')語法高帖,如下代碼,

var Hello = require('./hello')
hello = new Hello()
hello.setName('BYVoid')
...
...

這里畦粮,我們使用./test來獲取自定義文件模塊散址,這種通過相對路徑或絕對路徑是文件模塊的搜索方式。

3.3 搜索模塊的規(guī)則

node.js加載模塊時宣赔,遵循了如下的加載規(guī)則预麸,

  1. 核心模塊優(yōu)先級最高,直接使用名字加載儒将,再有命名沖突的時候首先加載核心模塊
  2. 文件模塊只能按照路徑加載 -- 相對路徑或絕對路徑吏祸,并且可以省略默認的.js后綴名
  3. 查找node_modules目錄,當我們在調用npm install <name>命令的時候钩蚊,會在當前目錄下創(chuàng)建node_module目錄來安裝模塊贡翘,當require遇到一個既不是核心模塊,又不是以路徑形式表示的模塊名稱時砰逻,會試圖在當前目錄下的node_modules目錄中查找是不是有這樣一個模塊鸣驱。如果沒有找到,則會在當前目錄的上一層的node_modules目錄中繼續(xù)查找蝠咆,反復執(zhí)行這一過程踊东,知道遇到根目錄位置。

相對路徑 - 例如: ./hello表示同級目錄刚操,../hello表示上層目錄

絕對路徑 - 例如: /Users/user/Desktop/js/hello

4. 參考鏈接

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末递胧,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子赡茸,更是在濱河造成了極大的恐慌缎脾,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,692評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件占卧,死亡現場離奇詭異遗菠,居然都是意外死亡,警方通過查閱死者的電腦和手機华蜒,發(fā)現死者居然都...
    沈念sama閱讀 92,482評論 3 392
  • 文/潘曉璐 我一進店門辙纬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人叭喜,你說我怎么就攤上這事贺拣。” “怎么了?”我有些...
    開封第一講書人閱讀 162,995評論 0 353
  • 文/不壞的土叔 我叫張陵譬涡,是天一觀的道長闪幽。 經常有香客問我,道長涡匀,這世上最難降的妖魔是什么盯腌? 我笑而不...
    開封第一講書人閱讀 58,223評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮陨瘩,結果婚禮上腕够,老公的妹妹穿的比我還像新娘。我一直安慰自己舌劳,他們只是感情好帚湘,可當我...
    茶點故事閱讀 67,245評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著甚淡,像睡著了一般大诸。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上材诽,一...
    開封第一講書人閱讀 51,208評論 1 299
  • 那天,我揣著相機與錄音恒傻,去河邊找鬼脸侥。 笑死,一個胖子當著我的面吹牛盈厘,可吹牛的內容都是我干的睁枕。 我是一名探鬼主播,決...
    沈念sama閱讀 40,091評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼沸手,長吁一口氣:“原來是場噩夢啊……” “哼外遇!你這毒婦竟也來了?” 一聲冷哼從身側響起契吉,我...
    開封第一講書人閱讀 38,929評論 0 274
  • 序言:老撾萬榮一對情侶失蹤跳仿,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后捐晶,有當地人在樹林里發(fā)現了一具尸體菲语,經...
    沈念sama閱讀 45,346評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,570評論 2 333
  • 正文 我和宋清朗相戀三年惑灵,在試婚紗的時候發(fā)現自己被綠了山上。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,739評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡英支,死狀恐怖佩憾,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤妄帘,帶...
    沈念sama閱讀 35,437評論 5 344
  • 正文 年R本政府宣布楞黄,位于F島的核電站,受9級特大地震影響寄摆,放射性物質發(fā)生泄漏谅辣。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,037評論 3 326
  • 文/蒙蒙 一婶恼、第九天 我趴在偏房一處隱蔽的房頂上張望桑阶。 院中可真熱鬧,春花似錦勾邦、人聲如沸蚣录。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽萎河。三九已至,卻和暖如春蕉饼,著一層夾襖步出監(jiān)牢的瞬間虐杯,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評論 1 269
  • 我被黑心中介騙來泰國打工昧港, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留擎椰,地道東北人。 一個月前我還...
    沈念sama閱讀 47,760評論 2 369
  • 正文 我出身青樓创肥,卻偏偏與公主長得像达舒,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子叹侄,可洞房花燭夜當晚...
    茶點故事閱讀 44,647評論 2 354

推薦閱讀更多精彩內容

  • Node.js是目前非彻火熱的技術,但是它的誕生經歷卻很奇特趾代。 眾所周知贯底,在Netscape設計出JavaScri...
    w_zhuan閱讀 3,613評論 2 41
  • Node.js是目前非常火熱的技術撒强,但是它的誕生經歷卻很奇特丈甸。 眾所周知,在Netscape設計出JavaScri...
    Myselfyan閱讀 4,072評論 2 58
  • topics: 1.The Node.js philosophy 2.The reactor pattern 3....
    宮若石閱讀 1,078評論 0 1
  • 1 Node.js模塊的實現 之前在網上查閱了許多介紹Node.js的文章,可惜對于Node.js的模塊機制大都著...
    zlx_2017閱讀 1,241評論 0 1
  • 于不經意間尿褪,我們乘著時光的步伐從懵懵懂懂的孩提走向成熟世故的青年睦擂。太多的變遷,太多的出世杖玲。更在不經意間我們丟失了去...
    左鴻鵠閱讀 278評論 0 0