2

I got to the point that I'd like to have a factory to manage all my dependencies for the modules in a single place instead of having a lot of statements using require all over the place in my code.

I've looked at some approaches that rely on AMD, but I'd like to know how to do it by using node.js / express combination with the OOB module loader which I think it uses common.js.

I've been thinking of doing something like this:

module.exports = {
lib:[],
load:function(name){
    if(this.lib[name]!==undefined  && this.lib[name]!==null){
        return this.lib[name];
    }

    switch(name)
    {
        case 'express':
            this.lib[name] = require('express');
            break;
        case 'morgan':      
            this.lib[name] = require('morgan');
            break;
        case 'body-parser': 
            this.lib[name] = require('body-parser');
            break;
    }
    console.log(this.lib);
    return this.lib[name];
    }
};

Some people say that's more than a factory its a mediator pattern, so either way I just wanted to illustrate my point.

my basic requirement is to handle all the dependencies from a single place in the system if I need to change a dependency I just change it on this file and automatically updates through the whole system.

so is there a better way to handle this? any Implementation that already have done this approach?

thanks!

2
  • Here's a way of making a factory pattern in JS thenodeway.io/posts/designing-factories. But normally people do the requires per file, you could try requireJS requirejs.org Commented Mar 23, 2015 at 22:01
  • Thanks the article seems quite interesting and also I came up with a couple of ideas pretty much similar to one mentioned in the article Commented Mar 24, 2015 at 20:21

1 Answer 1

2

Technically this is what require() does internally.

require('foo'); require('foo')

guarantees that it will load and run foo only once. The second call will return a cached copy from its internal array.

You can achieve the same naming indirection (and an API adapter if you'll ever decide to change the implementation without changing callers) by requiring JS files or your node modules that re-export modules you actually use (e.g. require('./my-express-wrapper') instead of require('express')).

if I need to change a dependency I just change it on this file and automatically updates through the whole system.

I'd be concerned that it will cause code to be surprising:

require('factory').load('body-parser'); // loads Formidable!?

I see little benefit in having such layer of indirection:

  • Even in the best case of drop-in-replacement it saves very little work, because project-global find'n'replace of require('foo') with require('bar') is an easy task in most text editors.

  • The hard part of replacing module (which is unlikely to be 100% compatible) is getting existing code to correctly work with it. This is not avoided by use of the factory pattern. You'll need to write an adapter either way, and sometimes it may even be better to actually change uses of the module everywhere than to write an emulation layer for an API that probably wasn't good anyway.

Sign up to request clarification or add additional context in comments.

3 Comments

what could be the case that you'd like to change a dependency on "runtime" in "production"?
@jack.the.ripper I'm not sure if understand correctly — you'd like to change implementation of parts of the app without restarting it? If you just swap between certain implementations (say JSON or XML serializer for output), then regular polymorphism/dependency injection or Strategy pattern works for this. Doing that via require would be weird.
that's the reason I wanted some sort of factory pattern as an implementation of inversion of control since I'm not a huge fan of DI in javascript

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.