由於不清楚如何分辨 module.exportsexports
所以我作了以下實驗記錄 :

index.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
const lib1 = require('./lib1.js');
const lib2 = require('./lib2.js');
const lib3 = require('./lib3.js');
const lib4 = require('./lib4.js');

const func = () => {
    return 'attr2';
};

var lib = {};
var lib = {
    attr1: 'attr1',
    attr2_1: func,
    attr2_2: func(),
    attr3: () => {
        return 'attr3 (closure)';
    }
};

// using object variable on local file
console.log(lib.attr1);
console.log(lib.attr2_1());
console.log(lib.attr2_2);
console.log(lib.attr3());

console.log('# Case1 ----');

console.log(lib1.attr1);
console.log(lib1.attr2_1());
console.log(lib1.attr2_2);
console.log(lib1.attr3());

console.log('# Case2 ----');

console.log(lib1.attr1);
console.log(lib1.attr2_1());
console.log(lib1.attr2_2);
console.log(lib1.attr3());

console.log('# Case3 ----');

console.log(lib3.attr1);
console.log(lib3.attr2_1());
console.log(lib3.attr2_2);
console.log(lib3.attr3());

console.log('# Case4 ----');

console.log(lib4.attr1);
console.log(lib4.attr2_1());
console.log(lib4.attr2_2);
console.log(lib4.attr3());

lib1.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
const func = () => {
    return 'attr2';
}

// Case1 : This work
module.exports.attr1 = 'attr1';
module.exports.attr2_1 = func;
module.exports.attr2_2 = func();
module.exports.attr3 = () => {
    return 'attr3 (closure)';
};

lib2.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
const func = () => {
    return 'attr2';
}

// Case2 : This work
module.exports = {
    attr1: 'attr1',
    attr2_1: func,
    attr2_2: func(),
    attr3: () => {
        return 'attr3 (closure)';
    }
};

lib3.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
const func = () => {
    return 'attr2';
}

// Case3 : This work
exports.attr1 = 'attr1';
exports.attr2_1 = func;
exports.attr2_2 = func();
exports.attr3 = () => {
    return 'attr3 (closure)';
};

lib4.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
const func = () => {
    return 'attr2';
}

// Case4 : Not work!
exports = {
    attr1: 'attr1',
    attr2_1: func,
    attr2_2: func(),
    attr3: () => {
        return 'attr3 (closure)';
    }
};

Conclusion

我做了4個case來實驗exports這個東西
但是case 4 出錯時,實在搞不懂是什麼原因
後來在stackoverflow上問一下馬上就有人拋出解答 : Is module.exports equal exports ?
解答是這個 :

1
2
3
4
5
6
var module = { exports: {} };  
var exports = module.exports;

// your code

return module.exports;

Case4會出錯的原因主要是 exports 被重新定義了
原本 exports = module.exports 的功能不見了
所以 index.js 在 require lib4.js 時就會變成 {}
這個需要體會一下
我這段問題也想了好久

其實用module.exports基本上不會有問題
我後來看別人說會使用exports的原因
似乎只是想簡短程式碼??
不過想想好像也只有這個可能吧

補充

  • What is the purpose of Node.js module.exports and how do you use it?

    module.exports is the object that’s actually returned as the result of a require call.

    The exports variable is initially set to that same object (i.e. it’s a shorthand "alias"), so in the module code you would usually write something like this:

    1
    2
    3
    4
    
    var myFunc1 = function() { ... };
    var myFunc2 = function() { ... };
    exports.myFunc1 = myFunc1;
    exports.myFunc2 = myFunc2;