RequireJS: Как определить модули, содержащие один "класс"?

У меня есть несколько классов JavaScript, каждый из которых реализован в своем собственном файле JavaScript. Для разработки эти файлы загружаются индивидуально, а для их создания они объединены, но в обоих случаях мне нужно вручную определить порядок загрузки, убедившись, что B приходит после A, если B использует A. Я планирую использовать RequireJS как реализация CommonJS Modules/AsynchronousDefinition для решения этой проблемы для меня автоматически.

Есть ли лучший способ сделать это, чем определять модули, каждый из которых экспортирует один класс? Если нет, как вам назвать то, что экспортирует модуль? Модуль "сотрудник", экспортирующий класс "Сотрудник", как в приведенном ниже примере, не считает DRY достаточным для меня.

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");
});

Ответ 1

предложение AMD позволяет просто вернуть значение для экспортируемого объекта. Но обратите внимание, что это особенность предложения AMD, это просто предложение API, и ему будет сложнее перевести модуль обратно в обычный модуль CommonJS. Я думаю, что все в порядке, но полезная информация.

Итак, вы можете сделать следующее:

Я предпочитаю модули, которые экспортируют функцию конструктора, чтобы начать с имени верхнего регистра, поэтому неоптимизированная версия этого модуля также будет находиться в 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;
    };
});

Теперь в другом модуле вы можете использовать модуль Employee следующим образом:

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

Ответ 2

В качестве дополнения к jrburke ответьте, что вам не нужно возвращать функцию конструктора напрямую. Для большинства полезных классов вы также захотите добавить методы через прототип, который вы можете сделать следующим образом:

define('Employee', function() {
    // Start with the constructor
    function Employee(firstName, lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    // Now add methods
    Employee.prototype.fullName = function() {
        return this.firstName + ' ' + this.lastName;
    };

    // etc.

    // And now return the constructor function
    return Employee;
});

Фактически это как раз образец, показанный в этом примере в requirejs.org.