Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A few Node module export styles. 1 seems to be the most used and I prefer it
// Style 1
// Export all manually
// Good: Calling functions inside the module is convenient
// Bad: module.exports becomes verbose and it's tedious to add new functions
function a() {
b()
}
function b() {
}
module.exports = {
a: a,
b: b
}
// Style 2
// Write all in module.exports
// Good: All functions in the same "package" (only good I could figure out)
// Bad: Hard to read. Wider indentation. Calling other functions is tedious
module.exports = {
a: function() {
module.exports.b()
},
b: function() {
}
}
// Style 3
// Export 'automatically' while writing functions
// Good: module.exports is clean and no hassle needed when adding functions
// Bad: Calling function inside the module is verbose and inconvenient
var exports = {}
exports.a = function() {
exports.b()
}
exports.b = function() {
}
module.exports = exports
// Style 4
// Good for a utils module
// Good: Calling functions inside module is convenient and module.exports is
// clean
// Bad: Syntax is not so clear, though that is arguable
var exports = {}
var a = exports.a = function() {
b()
}
var b = exports.b = function() {
}
module.exports = exports
@staltz
Copy link

staltz commented Mar 18, 2015

About style 1:

// Bad: module.exports becomes verbose and it's tedious to add new functions

Less verbose if you use ES6:

module.exports = {
  a,
  b
};

@kimmobrunfeldt
Copy link
Author

kimmobrunfeldt commented Mar 18, 2015

Nice! :)

@phoenixeliot
Copy link

phoenixeliot commented Sep 29, 2016

(Found this while researching the options, thought I'd contribute some things I've learned)


Style 1, which we agreed was the nicest at first, has the unfortunate effect that you can't stub out the functions when called by other functions in the module, from the outside, for testing. This is because the reference used from inside the module is for a function that is not on an object, whereas from the outside the reference is a property on the exported object.

Using your example, you can't use spyOn(exportedObject, 'b') and have calls to a use that stub.

The workaround is to call module.exports.b in a if you want to be able to stub b from the outside.


Style 2 does have a shorter way to call sibling functions from within the library: using this, which refers to module.exports because this scoping is strange like that. However, this breaks those references if you import the library like { a, b } = require('lib'); a() rather than lib = require('lib'); lib.a(), so I don't think I'd recommend it.

I think this problem applies to all the options that don't reference other functions in the file via method-style calling.

@Galaxy83
Copy link

Galaxy83 commented May 13, 2018

var _this = {}

_this.a = function() {
    _this.b()
}

_this.b = function() {
}

module.exports = _this

@gatsbyz
Copy link

gatsbyz commented Jun 6, 2018

Nice!

@p-g-krish
Copy link

p-g-krish commented Oct 23, 2018

Great Work

@mahemoff
Copy link

mahemoff commented Sep 25, 2020

Style 1 can now be more concise with ES6 literal shorthand:

module.exports = { a, b }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment