• All examples so far export a function that includes a new to a function to program object-oriented... see example at WRITING AND SUBMITTING MODULES (OR CHANGES), where require('MOD123') returns an object with the function .connect() which then says return new MOD123();.

    I want to expose function MOD123() to the user / application program and to be usable with new and to have access to the prototype which has application program settable constants.

    I expected
    exports.MOD123 = MOD123;
    to work, but invoking

    var MOD123 = require('MOD123'); 
    var mod123Instance = new MOD123();
    

    complains about MOD123 being an object and not a function (class):

    Uncaught Error: Constructor should be a function, but is Object
     at line 1 col 19
    var mod123Instance = new MOD123();
                       ^
    

    Of course - you will say - a module object is returned... because require() asks for one! ;-)... and I agree. :(

    So I helped myself the following way in the module definition - which is actually a class definition - and I am requiring a class:
    exports.class = function(){ return MOD123; };

    In the code I access the class the following way:

    var MOD123 = require('MOD123').class();
    var mod123Instance = new MOD123();
    

    Alternatively, I could have used in the definition
    exports.MOD123 = function(){ return MOD123; };

    var MOD123 = require('MOD123').MOD123();
    var mod123Instance = new MOD123();
    

    @Gordon, what is the technical reason that a module cannot be at the same time also a function?...

    I can assume that it has to do with the internal implementation that could lead to conflicts difficult to document...

    I see also the point that a module can include multiple classes... such as a UIElements module could provide Button, Checkbox, and EntryField classes.

    Allowing a module to be a function that acts like a class falls nicely in line with most client-side Web frameworks, where the module definition defines what the thing is that is returned by require(), and also how it has to be used.

    (The subject is triggered by prepping the SWBtn - Software Buttons - Many buttons from just one hardware button - as my first module for a pull-request... - see SWBtn - Software Buttons - Many buttons from just one hardware button.)

  • I'm actually just trying to be node.js compatible... Can you export functions that way in node.js?

    I think the issue right now is that the implementation keeps track of the original exports object, and returns that. However if you overwrite it with something else it may not notice. That could probably be changed though.

  • I've just modified this - it was only a few lines. If you use the latest from git then you should be able to return whatever you want

  • @Gordon, checked. It works - thanks for the nice Christmas gift...

    The corresponding export assignment is now:

    exports = MOD123;

    The module pattern of node.js and your modification implement now also a touch of require.js, which allows to give an application scoped name to a module (or class) to avoid name conflicts. Is require.js' protocol (or a part of it) on Espruino's radar?

    With require.js the application code for requiring multiple modules would then look like:

    require(['MOD123','OtherModule','OrOther­Class'],function(M123,OtherMod,OtherClas­s) {
        var myM123Instance = new M123();
        var myOtherModInst = new OtherMod();
        var myOtherClassInst = new OtherClass();
      });
    
  • Great, glad it's sorted!

    That one's definitely not in my plans at all I'm afraid!

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

How to create a module as a 'Class' / Constructor function usable with new - or: How to make require() return a function and not an object

Posted by Avatar for allObjects @allObjects

Actions