What is the best way to pass common variables into separate modules in Node.js?

I use separate router files as modules for the main application and the auth application. I cannot get a better way to pass variables (db client) to routers. I do not want to hard code it or transmit it with:

module.exports = function(app, db) { 

Maybe this is the best way to use the singleton register or use the db global variable?

What do you feel with design templates? Which method is the best and why?

+58
design-patterns
Apr 24 2018-12-21T00:
source share
4 answers

I found using addiction injection to convey things in order to be a better style. It would really look as if you have:

 // App.js module.exports = function App() { }; // Database.js module.exports = function Database(configuration) { }; // Routes.js module.exports = function Routes(app, database) { }; // server.js: composition root var App = require("./App"); var Database = require("./Database"); var Routes = require("./Routes"); var dbConfig = require("./dbconfig.json"); var app = new App(); var database = new Database(dbConfig); var routes = new Routes(app, database); // Use routes. 

This has several advantages:

  • This forces you to split your system into components with explicit dependencies, rather than hiding the dependencies somewhere in the middle of the file, where they are called require("databaseSingleton") or worse, global.database .
  • This makes unit testing very simple: if I want to isolate Routes , I can enter it with fake app and database parameters and test only the Routes code itself.
  • It combines all your postings with the object graph in one place, namely the root structure (which in this case is server.js , the entry point to the application). This gives you one place to watch how everything fits into the system.

One of the best explanations I've seen for this is an interview with Mark Siman , author of the excellent book Injection Dependency in.NET>. It applies in the same way as JavaScript, and especially to Node.js: require often used as a classic service locator instead of a simple module system.

+103
Apr 26 2018-12-12T00:
source share

I suggest you create a settings file with a db instance and other things that you need to use globally, like "singleton".

For example, I have settings.js with my redis db client:

 var redis = require('redis'); exports.redis = redis.createClient(6379, '127.0.0.1'); 

And in the other few modules, I turn it on:

 var settings = require('./settings'); setting.redis.<...> 

A lot of the time, including it, I always have one instance of the db connection.

+2
Apr 25 2018-12-12T00:
source share

You can save all the template code for connecting your modules if you use the dependency injection infrastructure

This answer lists some of them. I also created a simplified DI diagram here .

EDIT: below is a copy of the response form if the page changes




require The dependency management method in Node.js, and certainly it is intuitive and efficient, but it also has its limitations.

My advice is to take a look at some of the Dependency injection containers available today for Node.js to get an idea of ​​what their pros and cons are. Some of them:

Just to name a few.

Now the real question is: what can you achieve with the Node.js DI container compared to the simple require ?

Pros:

  • better testability: modules take their dependencies as input
  • Inversion of Control: Choose how to connect your modules without touching the main code of your application.
  • customizable algorithm for solving modules: dependencies have "virtual" identifiers, usually they are not tied to a path in the file system.
  • Improved extensibility: Enabled by IoC and "virtual" identifiers.
  • Other bizarre things are possible:
    • Asynchronous initialization
    • Module Lifecycle Management
    • Extensibility of the DI container itself
    • Can easily implement higher level abstractions (e.g. AOP)

Minuses:

  • Unlike Node.js "experience": without using require , it definitely seems that you are deviating from Node's way of thinking.
  • The relationship between addiction and its implementation is not always obvious. Dependency can be resolved at runtime and under the influence of various parameters. Code becomes more difficult to understand and debug.
  • Slower startup time
  • Maturity (at the moment): none of the current solutions are really popular at the moment, so there are not so many tutorials, not ecosystems, not battles.
  • Some DI containers will not play well with modules such as Browserify and Webpack.
+1
Jun 25 '16 at 14:34
source share

It is completely deprecated, but you can use global in a script:

  global.foo = new Foo(); 

in another script:

  foo.bar(); 

You can also use an existing constant:

  Object.foo = new Foo(); 

And here:

  Object.foo.bar(); 
0
Feb 23 '14 at 16:55
source share



All Articles