The difference between module.exports and exports

There is no magic. Your module code is sandwiched between the two items in this array, and eval’d:

NativeModule.wrapper = [
  '(function (exports, require, module, __filename, __dirname) { ',

The magic variables you can use in modules - exports, require, module, __filename, and __dirname are not magic, they are just parameters to the function that is invoked when your module is loaded.

Initially, exports and module.exports point at the same empty object.

You can add properties to this object using either module.exports or exports since they both point to the same object, it doesn’t matter which you use.

If you add = "bar" and module.exports.baz = "boz" then your module’s exported object will look like:

{foo: "bar", baz: "boz"}

…but, what if you want to export a function, or a string, or a unicorn?

This is when the difference between exports and module.exports is important.

If you remember nothing else from this article, remember this:

module.exports wins

What this means is that whatever object module.exports is assigned to is the object that is exported from your module.

If you want to export a function from your module and you assign it to exports and not module.exports then this happens:

Ruh roh! Your module will export an empty object, not the function that you probably intended it to export!

If you want to export something other than an empty object and you want to use exports elsewhere in your module, you’ll need to reassign them both:

exports = module.exports = function () {/* ... */} = "bar"

…and that’s it. Simple.

02 August 2014