Search code examples
javascriptcommonjsrequirejs

RequireJS: How to define modules that contain a single "class"?


I have a number of JavaScript "classes" each implemented in its own JavaScript file. For development those files are loaded individually, and for production they are concatenated, but in both cases I have to manually define a loading order, making sure that B comes after A if B uses A. I am planning to use RequireJS as an implementation of CommonJS Modules/AsynchronousDefinition to solve this problem for me automatically.

Is there a better way to do this than to define modules that each export one class? If not, how to you name what the module exports? A module "employee" exporting a class "Employee", as in the example below, doesn't feel DRY enough to me.

define("employee", ["exports"], function(exports) {
    exports.Employee = function(first, last) {
        this.first = first;
        this.last = last;
    };
});

define("main", ["employee"], function (employee) {
    var john = new employee.Employee("John", "Smith");
});

Solution

  • The AMD proposal allows you to just return a value for the exported object. But note that is a feature of the AMD proposal, it is just an API proposal, and will make it harder to translate the module back to a regular CommonJS module. I think that is OK, but useful info to know.

    So you can do the following:

    I prefer modules that export a constructor function to start with an upper-case name, so the non-optimized version of this module would also be in Employee.js

    define("Employee", function () {
        //You can name this function here,
        //which can help in debuggers but
        //has no impact on the module name.
        return function Employee(first, last) {
            this.first = first; 
            this.last = last;
        };
    });
    

    Now in another module, you can use the Employee module like so:

    define("main", ["Employee"], function (Employee) {
        var john = new Employee("John", "Smith");
    });