preface

Exports and module.exports in Node.js are a lot of things that can be confusing and confusing. So let’s sort out the relationship from the beginning.

source

When developing Node.js applications, many modules need to be imported before they can be used, but why can exports and module.exports be used without reference?

In fact, Node.js applications encapsulate the contents of JavaScript files during compilation. Such as:

// hello.js
const hello = function () {
	console.log('Hello world');
}
module.exports = {
	hello
}
// Wrap the header and tail into the js code
(function (exports, require, module, __filename, __dirname) {
    const hello = function () {
        console.log('Hello world');
    }
    module.exports = {
        hello
    }
})
Copy the code

After header and tail encapsulation, the individual modules are scoped to avoid contaminating global variables and to enable each module to use them without introducing them. These variables are, in turn, the exports property of the current module, the require() method, the current module itself (module), the full path to the file system, and the file directory.

The difference between

Exports and module.exports should be equivalent if node. js defines exports as a module object. Exports and module.exports are both initialized with {}.

// hello.js
const hello = function () {
    console.log('Hello world');
}
console.log('Initial value ==========');
console.log(exports);
console.log(module.exports);
module.exports = {
    hello
}
// Output the resultInitial value ========== {} {}Copy the code

Exports: {exports} {exports: {exports: {exports: {exports: {exports: {exports: {exports: {}}}}}

Exports is just a reference to the exports of the Module object. We can help modify the value of module.exports by modifying the value of the object pointed to by exports.

  • Using exports
const hello = function () {
    console.log('Hello world');
}
exports.hello = {
    hello
}
console.log('Change value ==========');
console.log(exports);
console.log(module.exports);
// Output the resultChange the value ========== {hello: { hello: [Function: hello] } }
{ hello: { hello: [Function: hello] } }
Copy the code

Exports and module.exports refer to the same memory region, so if we modify the data of the exports object, module.exports will also change.

  • Exports using module.exports
// hello.js
const hello = function () {
    console.log('Hello world');
}
module.exports = {
    hello
}
console.log('Change value ==========');
console.log(exports);
console.log(module.exports);
// Output the resultChange the value ========== {} {hello: [Function: hello] }
Copy the code

Exports = {}, module.exports = {}, module.exports = {}, module.exports = {}, module.exports = {}, module.exports = {}, module.exports = {}, module. So the values are different, but you can still call hello() if you import hello.js from another file, which means that you exported module.exports instead of exports.

  • Exports directly
// hello.js
const hello = function () {
    console.log('Hello world');
}
exports = {
    hello
}
console.log('Change value ==========');
console.log(exports);
console.log(module.exports);
// Output the resultChange the value ========== {hello: [Function: hello] }
{}
Copy the code

Using this method to export a file will cause an error when the hello() method is called in another file, because the exported object of the file module is empty, and of course there is no hello() method. This problem is also caused by the change of the memory region pointed to.

conclusion

  1. Exports is an attribute of the Module object. Exports and module.exports originally refer to the same memory region.
  2. Module. exports can be changed by changing the value of exports without changing the memory orientation of exports;
  3. Exports use module.exports to avoid confusion.