我是nodejs的新手, 尝试了解其他文件的包含功能。
我发现module.exports
和exports
可以解决我的问题,
但我不知道两者之间有什么区别。
我做了一些研究,发现exports = module.exports
参考:Understanding module.exports and exports in Node.js
var exports = module.exports = {};
但是我仍然不确定,所以我做了实验:
index.js
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
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
const func = () => {
return 'attr2';
}
// Case2 : This work
module.exports = {
attr1: 'attr1',
attr2_1: func,
attr2_2: func(),
attr3: () => {
return 'attr3 (closure)';
}
};
lib3.js
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
const func = () => {
return 'attr2';
}
// Case4 : Not work!
exports = {
attr1: 'attr1',
attr2_1: func,
attr2_2: func(),
attr3: () => {
return 'attr3 (closure)';
}
};
case4将返回错误:(来自vscode调试)
...
# Case4 ----
undefined
C:\Users\Scott\Documents\module_export\index.js:49
console.log(lib4.attr2_1());
^
TypeError: lib4.attr2_1 is not a function
at Object.<anonymous> (C:\Users\Scott\Documents\module_export\index.js:49:18)
at Module._compile (internal/modules/cjs/loader.js:689:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
at Module.load (internal/modules/cjs/loader.js:599:32)
at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
at Function.Module._load (internal/modules/cjs/loader.js:530:3)
at Function.Module.runMain (internal/modules/cjs/loader.js:742:12)
at startup (internal/bootstrap/node.js:282:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:743:3)
case1、2、3 =>正常。
但是为什么case4是错误的?
var exports = module.exports = {};
不正确吗?
答案 0 :(得分:1)
您在这里做什么
var exports = module.exports = {};
exports = {
attr1: 'attr1',
attr2_1: func,
attr2_2: func(),
attr3: () => {
return 'attr3 (closure)';
}
};
正在将名为exports
的变量重新分配给一个全新的对象。名为exports
的变量不再与module.exports
指向同一对象; module.exports
保持不变,为空对象。因此,当其他模块尝试从lib4
导入时,它们只会得到一个空对象。
您必须像情况3一样对exports
变量进行变异,或者像您一样在exports
上重新分配module
属性在情况2中做(或在情况1中对现有的exports
对象进行突变)。
这与导入/导出没有特别关系:可以在此处看到相同的行为:
// boilerplate, so that the live snippet will run
const module = {};
var exports = module.exports = {};
const func = () => {
return 'attr2';
}
// Case4 : Not work!
exports = {
attr1: 'attr1',
attr2_1: func,
attr2_2: func(),
attr3: () => {
return 'attr3 (closure)';
}
};
// module.exports is still the empty object:
console.log(module.exports.attr1);
或者在这里:
var obj1 = {};
var obj2 = obj1;
obj2 = { foo: 'foo' }; // reassigning obj2 does not affect obj1
console.log(obj1.foo); // undefined, obj1 is just an empty object, after all
除非module.exports
以某种方式填充,否则不会导出任何内容。
答案 1 :(得分:1)
就像您提到的,exports
是对module.exports
的引用。导入模块后,将返回module.exports
中的值。
通过将exports
分配给另一个对象,您并没有更改module.exports
的值,因此不会出现此错误。
答案 2 :(得分:-1)
在节点js中,exports
是一个获取器/设置器。一旦尝试获取导出值(exports
),它将返回module.exports。但是,如果您尝试设置导出值(exports = something
),它将更改module.exports的值。