/

[nodejs] module.exports 與 exports 的差異

前言

nodejs 中有許多的特性或是方便的功能我們會使用,但實際上不知道內部處理的機制。本篇要探討的是匯出模組的兩種方式 modules.exports 以及 exports

結論(TL;DR)

The exports variable is available within a module’s file-level scope, and is assigned the value of module.exports before the module is evaluated.

在不更改 modules.exportsexports 的前提下,兩者是一樣的。
使用 require() 引入模組,實際上是去 modules.exports 找模組,所以 exports 只是用來輔助 modules.exports

用程式碼角度來看就是:

1
2
3
module.exports = exports = function Constructor() {
// ... etc.
};
  • 兩者初始指向同一個物件
  • 兩者有一指向新物件,則斷開兩者關係
  • require 是去 module.exports 找模組

Nodejs Doc - modules exports

實驗時間

實驗一 (兩者初始指向同一個物件)

m.js:

1
2
3
4
exports.a = "str_a";
console.log(module.exports); //{ a: 'str_a' }
console.log(exports); //{ a: 'str_a' }
console.log(module.exports === exports); //true

我們由以上實驗可以得知 exportsmodule.exports 是指向同一個物件

實驗二 (module.exports 指向新物件,斷開關係)

m.js:

1
2
3
4
5
6
exports.a = "str_a";
console.log(exports); //{ a: 'str_a' }
console.log(module.exports); //{ a: 'str_a' }
module.exports = { b: "str_b" }; // 此時將 module.exports 重新給定一物件,斷開與 exports 之關係
console.log(exports); //{ a: 'str_a' }
console.log(module.exports); //{ b: 'str_b' }

實驗三 (require 是去 module.exports 找模組)

m.js:

1
2
module.exports = { a: 123 };
exports.b = "456";

main.js:

1
2
let x = require("./m.js");
console.log(x); //{ a: 123 }