Why must a module's exports be declared at the bottom of a file?
Asked Answered
G

1

14

I have the following redacted code:

module.exports = {
  read: read,
  write: write,
};

var read = function(parameters, config, next) {
  /* <snip> */
};

var write = function(parameters, config, next) {
  /* <snip> */
};

If I go to require() this file elsewhere, it will crash node and say that the required object has no method read or write. Wouldn't variable hoisting pull the functions above the modules.export = { ... };?

Guide answered 21/5, 2014 at 19:6 Comment(0)
S
21

It's the syntax you use to declare functions that matters due to function hoisting. If you declare those functions like this, they will get "hoisted" up in the scope and all is well.

module.exports = {
  read: read,
  write: write,
};

function read(parameters, config, next) {
  /* <snip> */
};

function write(parameters, config, next) {
  /* <snip> */
};

Side note: Named functions like in my snippet, as opposed to anonymous functions assigned to variables like in your snippet, are easier to debug and profile because their name gets included in stack traces.

Schmeltzer answered 21/5, 2014 at 19:22 Comment(5)
Why would a variable not get hoisted above the module.exports assignments? Is module some special node object that gets declared and hoisted before any other code in the file is rendered?Guide
Variables don't get hoisted. Just named functions declared without "var".Schmeltzer
Ahhh, went back and re-read your linked article. The declaration of the variable is hoisted, but the value (in my case a function) is not assigned until later, whereas a named function will get hoisted along with its logic. Gotchya.Guide
Just to expand on your side note, you can "name" anonymous functions assigned to variables and get the same benefits in your stack trace while debugging :) var someFunc = function someFunc() { //... };. A little repetitive maybe but it helps so much when debugging. You can name any anonymous function, even ones you're passing in as an argument: db.query('stuff', function queryCallback() { //... }); and it shows up as a named function when debugging :DSlipslop
@Chev I did not know you could name functions passed as arguments! Thank you!Agnosia

© 2022 - 2024 — McMap. All rights reserved.