NodeJS - How to assign constructor to module.exports in self-executing function?
Asked Answered
S

1

6

I'm trying to assign a constructor in a self-executing function in NodeJS. I'm pretty sure it's not working because my parameter is a variable pointing to module.exports, but I'm curious if there's a way to make it work while staying as close to the self-executing format as possible.

Here's how the code is being called...

var TemplateEngine = require('./templateEngine');
templateEngine = new TemplateEngine({engine: 'swig'}); // "object is not a function"

Here's an example of code that works fine...

var assert = require('assert');
var swig = require('swig');

// Constructor
var TemplateEngine = function(args) {
    assert.ok(args.engine, 'engine is required');
    var templateEngine = {};

    templateEngine.engine = args.engine;

    templateEngine.Render = function(templateString, model) {
        var result = swig.render(templateString, model);
        return result;
    };

    return templateEngine;
};

module.exports = TemplateEngine;

and here's an example of the code style I'd like to use, but which produces a "TypeError: Object is not a function" error because I'm not actually assigning to module.exports, just a variable that copied whatever it was pointing to.

(function(templateEngine) {
    var assert = require('assert');
    var swig = require('swig');

    templateEngine = function(args) {
        assert.ok(args.engine, 'engine is required');
        var templateEngine = {};

        templateEngine.engine = args.engine;

        templateEngine.Render = function (templateString, model) {
            var result = swig.render(templateString, model);
            return result;
        };

        return templateEngine;
    };
})(module.exports);

Is there a way for me to use the above self-executing format and have my module export a Constructor?

Strabismus answered 13/2, 2015 at 19:44 Comment(4)
module.exports needs to be assigned in the 2nd code, maybe something like module.exports=new templateEngine(); ?Doolie
you have to many templateEngine variables...Benzophenone
This style is not needed. You can use it to hide private variables... but on client side. With modules in nodejs everything not assigned to module.exports is private so this pattern is useless.Benzophenone
I agree it doesn't provide any functional benefit, but it's pretty nice for organization. You can name module.exports whatever you want in the parm, like "controller" then whatever you assign to controller.someProp = or controller.someFunction = is what you're exporting. I suppose you can do the same thing with an object, so it's more of a preference. I'm realizing all of that is lost when exporting a constructor, so it might be extra useless in this case.Strabismus
M
9

In your second example, you are simply overwriting the templateEngine parameter, and that's not going to have any effect.

To get the same result as your first example, simply:

Pass module into your IIFE:

(function(module) {

})(module);

Assign a property to that:

(function(module) {
    var assert = require('assert');
    var swig = require('swig');

    module.exports = function (args) {
       ...
    };

})(module);
Muro answered 13/2, 2015 at 19:51 Comment(2)
Wow. Don't know why I didn't think of that. I'll try it when I get home, but I'm thinking this will work great.Strabismus
Thank you for your answer! Whilst it wasn't in direct relation to what I was doing, this really was helpful to create my solution!Elver

© 2022 - 2024 — McMap. All rights reserved.