node.js入門 - 模塊module

1. node.js模塊概述

爲了讓node.js的文件能夠相互調用,node.js提供了一個簡單的模塊系統。模塊是node.js應用程序基本的組成部分,文件和模塊是一一對應的。換言之,一個node.js文件就是一個模塊,這個文件多是javascript代碼、json或者編譯過的c/c++擴展。javascript

其中http、fs、net等都是node.js提供的核心模塊,使用c/c++實現,外部用javascript封裝。html

2. 建立模塊的兩種方式

建立模塊有兩種方式,java

  • 經過exports建立node

  • 經過module.exports建立c++

2.1 經過exports建立模塊

node.js中,建立一個模塊很是簡單,咱們建立一個main.js文件,它引用了hello模塊,代碼以下,npm

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

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

./表明當前目錄,node.js默認後綴爲js。json

node.js提供了exportsrequire兩個對象,其中exports是模塊公開的接口,require用於從外部獲取一個模塊的接口,即所獲取模塊的exports對象。函數

接下來咱們建立hello.js文件,以下代碼所示,工具

exports.world = function() {
  console.log('hello world')
}

以上示例中,hello.js經過exports對象把world做爲模塊的訪問接口,在main.js中經過require('./hello')加載這個模塊,而後就能夠直接訪問hello.js中exports對象的成員函數了。

2.2 經過module.exports建立模塊

有時候咱們只是想把一個對象封裝到模塊中,以下格式,

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區別

爲了更好地解釋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只想同一塊內存地址的內容發生了改變,因此a的值改變也體現了出來;當b被覆蓋時,b只想了一塊新的內存,而a仍是隻想原來的內存,因此最後兩個輸出不同。

明白了上面的例子以後,只須要指點3點就能瞭解exports和module.exports的區別了,

  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 搜索文件模塊

在前面建立模塊的demo中,經過require('./hello')語法,以下代碼,

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

這裏,咱們使用./test來獲取自定義文件模塊,這種經過相對路徑或絕對路徑是文件模塊的搜索方式。

3.3 搜索模塊的規則

node.js加載模塊時,遵循了以下的加載規則,

  1. 核心模塊優先級最高,直接使用名字加載,再有命名衝突的時候首先加載核心模塊

  2. 文件模塊只能按照路徑加載 -- 相對路徑或絕對路徑,而且能夠省略默認的.js後綴名

  3. 查找node_modules目錄,當咱們在調用npm install <name>命令的時候,會在當前目錄下建立node_module目錄來安裝模塊,當require遇到一個既不是核心模塊,又不是以路徑形式表示的模塊名稱時,會試圖在當前目錄下的node_modules目錄中查找是否是有這樣一個模塊。若是沒有找到,則會在當前目錄的上一層的node_modules目錄中繼續查找,反覆執行這一過程,知道遇到根目錄位置。

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

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

4. 參考連接

相關文章
相關標籤/搜索