Nodejs教程10:Nodejs的模組化

LeeChen發表於2019-03-02

閱讀更多系列文章請訪問我的GitHub部落格,示例程式碼請訪問這裡

Nodejs定義模組

Nodejs的模組化由於出現的較早,因此它遵循的是CommonJS規範,而非ES6的模組化。

在Nodejs的模組化中,最常用到的有module物件、exports物件、require方法。

其中module和exports用於輸出模組,require用於引用模組。

一個簡單的模組例子

示例程式碼:/lesson10/module1.js、/lesson10/require.js

先新建一個module1.js檔案,程式碼如下:

module.exports.a = 1
module.exports.b = 2

let c = 3
複製程式碼

在require.js中,引入模組並列印:

const module1 = require('./module1')

console.log(module1)
複製程式碼

可以看到列印結果:{ a: 1, b: 2 }。

這段程式碼的含義如下:

  1. module1.js對外輸出了module.exports,module.exports為一個物件,它含有a和b屬性。
  2. module1.js中雖然定義了變數c,但它只在module1.js這個模組中存在,從外部無法訪問。
  3. 在require.js中引用module1.js,必須使用相對路徑或絕對路徑。
  4. 若引用時不帶路徑,而是直接使用模組名稱,則會預設引用專案目錄下的node_modules資料夾下的模組,如:
const module2 = require('module2')

console.log(module2)  // { a: 1, b: 2 }
複製程式碼

若此時專案目錄下的node_modules資料夾下存在module2.js檔案,則會引用該檔案。

若不存在,則會查詢系統的node_modules資料夾下,即全域性安裝的模組,是否存在module2。

若還不存在該模組,則會報錯。

通過require匯入的模組,可以被任意命名,因此寫成const a = require('module2')也是可以的。

module.exports

上面這個例子中的模組匯出,還可以省略module,直接寫成exports.a = 1; exports.b = 1; ...。

但直接使用exports匯出,也僅支援這種寫法,若寫成:

exports = {
  a: 1,
  b: 2
}

複製程式碼

在引用模組時,只能接收到{},也就是說exports只支援exports.a = 1;這樣的語法。

如果要將整個模組直接定義為一個物件、函式、變數、類,則需要使用module.exports = 123。

如下:

示例程式碼:/lesson10/module3.js

module.exports = {
  a: 1,
  b: 2
}

module.exports = 123

module.exports = {
  a: 1,
  b: 2,
  c: 3
}

module.exports = function () {
  console.log('test')
}

module.exports = class {
  constructor(name) {
    this.name = name
  }

  show() {
    console.log(`Show ${this.name}`)
  }
}
複製程式碼

module.exports可以讓模組被賦值成任意型別,但需要注意的是此時module.exports類似於一個模組內的全域性變數。

對它的重複賦值,只有最後的值有效,之前的值會直接被覆蓋。

在這個例子中,module3.js模組最終匯出為一個類。

因此,通常推薦使用module.exports,可以避免出錯。

相關文章