yolenoyer
yolenoyer

Reputation: 9445

How to run Node.js module initialization properly

In a Node.js module, I need to run some initialization code, some code to be run only once, to parse a YAML config file on my application startup.

As a Node.js novice, I noticed that modules are loaded once, and only once (and that's very fine like that). I mean:

// ./mymodule.js

console.log('mymodule.js was run');

... displays the given message only once, even if ./mymodule.js was needed in multiple loaded modules. And that's fine.

So, for my init code, I can imagine to implement it simply like that:

// ./mymodule.js

function mymodule_init()
    // Parse my config file
    // ...
    // Done
}

// Run my init:
mymodule_init();

console.log('mymodule.js was run');

But is it the right way to run my initialization code? Isn't there a more regular way to do it, like subscribing to a kind of 'module_init' event, which would guarantee that my init code would be run once and only once?

Note: I found this SO link about the question : Initialize nodejs module once, use many times, but there's no really frank answer about it.

Upvotes: 6

Views: 15369

Answers (2)

saille
saille

Reputation: 9191

Node.js documention on the subject of module caching states:

Multiple calls to require('foo') may not cause the module code to be executed multiple times. This is an important feature. With it, "partially done" objects can be returned, thus allowing transitive dependencies to be loaded even when they would cause cycles.

So I don't see anything wrong with initialization code executed directly in a module. I am doing this in several Node.js apps, as you indicate, like so:

// ./mymodule.js

function mymodule_init()
    // Parse my config file
    // ...
    // Done
}

// Run my init:
mymodule_init();

console.log('mymodule.js was run');

Upvotes: 6

Ivan Drinchev
Ivan Drinchev

Reputation: 19581

Your question will mostly have opinionated answers, but anyway.

I usually use a singleton class for this kind of work.

Something like

// config.js

function Config() {
   this.config = parseYAML("./path/to/yaml-file.yaml");   
}

Config.prototype.get = function( property ) {
   return this.config[property];
}

module.exports = new Config();

And in your app or modules

// app.js

const config = require( "./config.js" );

console.log( config.get("some-config-property") );

Most of the modules either use this or an anonymous function, which is called immediately e.g.

module.exports = (function() {
   return parseYAML("./path/to/yaml-file.yaml");
})();

Both cases you will do it right, so it actually doesn't matter so much, as long as your code is readable.

Upvotes: 5

Related Questions