RequireJS: Как определить модули, которые содержат один «класс»? - PullRequest
67 голосов
/ 02 февраля 2011

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

Есть ли лучший способ сделать это, чем определять модули, каждый из которых экспортирует один класс?Если нет, то как вы называете, что модуль экспортирует?Модуль "employee", экспортирующий класс "Employee", как в примере ниже, мне не кажется 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");
});

Ответы [ 2 ]

110 голосов
/ 02 февраля 2011

Предложение 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");
});
102 голосов
/ 23 апреля 2012

В дополнение к ответу 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 .

...