首页 > 解决方案 > Is module.exports equal exports

问题描述

Im a newcomer on nodejs, try to know how include function from other files.

I found module.exports and exports can sovle my problem, but I dont know what's different between the two.

I do some research, and found exports = module.exports
ref: Understanding module.exports and exports in Node.js

var exports = module.exports = {};

But I still not sure of that, so I do the experiment :

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 will return error : (from vscode debug)

...

# 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 => is working fine.

but why case4 is error? is the var exports = module.exports = {}; not true?

标签: javascriptnode.js

解决方案


What you're doing here

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

is reassigning the variable named exports to an entirely new object. The variable named exports no longer points to the same object as module.exports; module.exports remains unchanged, as the empty object. So, when other modules try to import from lib4, they'll just get an empty object.

You must mutate the exports variable, like you're doing in case 3, or you must reassign the exports property on module, like you're doing in case 2 (or mutate the existing exports object in case 1).

This doesn't particularly have anything to do with imports/exports: the same behavior can be seen here:

// 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);

Or here:

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

Unless module.exports somehow gets populated, nothing will be exported.


推荐阅读