{"id":136,"date":"2018-12-01T23:26:41","date_gmt":"2018-12-02T07:26:41","guid":{"rendered":"https:\/\/www.jwdev.com\/?p=136"},"modified":"2018-12-01T23:26:41","modified_gmt":"2018-12-02T07:26:41","slug":"the-best-way-to-do-module-exports-in-node","status":"publish","type":"post","link":"https:\/\/www.jwdev.com\/?p=136","title":{"rendered":"The best way to do module.exports in node"},"content":{"rendered":"<p>Recently had a question asked regarding the right way to export an object in node. Consider the following code<\/p>\n<blockquote>\n<pre>class Foo {\r\n    constructor() {\r\n        this.foo = 'foo'\r\n    }\r\n}\r\n\r\nmodule.exports = function() {\r\n    return new Foo()\r\n}<\/pre>\n<\/blockquote>\n<p>We have a class that exports a function which returns a shiny new <code>Foo<\/code>\u00a0object.<\/p>\n<p>Great! Then someone asks. Why bother wrapping it in a function when you can just return the object? Let&#8217;s see.<\/p>\n<blockquote>\n<pre>class Foo {\r\n    constructor() {\r\n        this.foo = 'foo'\r\n    }\r\n}\r\nmodule.exports = new Foo()<\/pre>\n<\/blockquote>\n<p>Basically the same thing right? Not so fast! Yes, the function is gone and now it is returning that shiny new <code>Foo<\/code>\u00a0object directly. However this second version will only create one <code>Foo<\/code>\u00a0object. You can require the module anywhere in your code and it will always return the same <code>Foo<\/code>\u00a0object.<\/p>\n<p>Take a look at this REPL (Read-Eval-Print-Loop)<\/p>\n<blockquote>\n<pre>&gt; foo=require('.\/foo')()\r\nFoo { foo: 'foo' }\r\n&gt; foo.foo='bar'\r\n'bar'\r\n&gt; bar=require('.\/foo')()\r\nFoo { foo: 'foo' }\r\n&gt; foo\r\nFoo { foo: 'bar' }<\/pre>\n<\/blockquote>\n<p>As you can see above this is the foo module from our first example. You can tell by the trailing parens <code>()<\/code>\u00a0on the require statement. That is executing the function that is exported by the module.<\/p>\n<p>We assigned the <code>Foo<\/code> object to a variable named foo. You can see that the property &#8216;foo&#8217; of object foo is set to a string with the value &#8216;foo&#8217;.<\/p>\n<p>Next we set the property foo to a string &#8216;bar&#8217; and then we require foo again. This time we assign it the variable bar and we see that it is in fact a brand new <code>Foo<\/code>\u00a0object because <code>bar.foo<\/code>\u00a0equals &#8216;foo&#8217; but <code>foo.foo<\/code>\u00a0equals &#8216;bar&#8217;<\/p>\n<p>(wishing I&#8217;d used different variables at this point, oh well too late for that now) Still with me? Great!<\/p>\n<p>So everything looks good&#8230; well, that is if you want a brand new <code>Foo<\/code>\u00a0every time you require the module, but what about that second example. Let&#8217;s have a look.<\/p>\n<blockquote>\n<pre>&gt; foo=require('.\/foo')\r\nFoo { foo: 'foo' }\r\n&gt; bar=require('.\/foo')\r\nFoo { foo: 'foo' }\r\n&gt; bar.foo='bar'\r\n'bar'\r\n&gt; foo\r\nFoo { foo: 'bar' }\r\n&gt; baz=require('.\/foo')\r\nFoo { foo: 'bar' }<\/pre>\n<\/blockquote>\n<p>Here we require the same <code>foo<\/code>\u00a0module twice assign it once to foo and once to bar. They are both the same, as you would expect however this time when we set bar.foo to the string value &#8216;bar&#8217; we can actually see that we only have a single object because when we check our foo object the foo property is now a string with the value &#8216;bar&#8217;.<\/p>\n<p>Just to make the point extra clear we require foo a third time and assign it to baz. Again you see that <code>baz.foo<\/code> equals &#8216;bar&#8217;.<\/p>\n<p>This is what is known as a <strong>Singleton<\/strong>, the module only creates one object the first time it is used and then it hands that same object out every time it is required again.<\/p>\n<p>This is a very important concept to understand and remember. One way isn&#8217;t better than another. The method you choose depends on what you are trying to accomplish. For example if you have a logging module that you want to configure once but use everywhere then you&#8217;ll want to use the second example but if you&#8217;re creating a catalog of items each with their own distinct properties you&#8217;ll want to stick with the first example.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Recently had a question asked regarding the right way to export an object in node. Consider the following code class Foo { constructor() { this.foo = &#8216;foo&#8217; } } module.exports = function() { return new Foo() } We have a class that exports a function which returns a shiny new Foo\u00a0object. Great! Then someone asks. [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,25,10],"tags":[],"class_list":["post-136","post","type-post","status-publish","format-standard","hentry","category-devel","category-nodejs","category-software"],"_links":{"self":[{"href":"https:\/\/www.jwdev.com\/index.php?rest_route=\/wp\/v2\/posts\/136","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.jwdev.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.jwdev.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.jwdev.com\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.jwdev.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=136"}],"version-history":[{"count":1,"href":"https:\/\/www.jwdev.com\/index.php?rest_route=\/wp\/v2\/posts\/136\/revisions"}],"predecessor-version":[{"id":137,"href":"https:\/\/www.jwdev.com\/index.php?rest_route=\/wp\/v2\/posts\/136\/revisions\/137"}],"wp:attachment":[{"href":"https:\/\/www.jwdev.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=136"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.jwdev.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=136"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.jwdev.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=136"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}