Миграция с простого шаблона Module на RequireJS AMD

Я использую шаблон модуля в своем приложении Javascript и хочу перейти на RequireJS и AMD.

Моя текущая реализация выглядит так:

// Module main : Module.js
var myModule = (function(my, $, undefined) {
    'use strict';

    var m_privateMembers;
    var m_stuff = new my.Pear({color:"green"});

    //---------------------------------------

    function privateFunctions(args) {
    }

    //-----------------------------------

    my.publicFunctions = function(args) {
    };

    return my;
})(myModule || {}, jQuery);



// Module class Fruit : Module.Fruit.js
var myModule = (function(my, $, undefined) {
    'use strict';

    my.Fruit = Object.makeSubclass();

    my.Fruit.prototype._init = function() {

    };

    my.Fruit.prototype.someClassFunction = function() {
    };

    return my;
})(myModule || {}, jQuery);


// Module class Pear : Module.Pear.js
var myModule = (function(my, $, undefined) {
    'use strict';

    my.Pear = Fruit.makeSubclass();

    my.Pear.prototype._init = function(args) {
        this.m_someClassMember = args;
    };

    my.Pear.prototype.someClassFunction = function() {
    };

    return my;
})(myModule || {}, jQuery);

В моем index.html я использую html-теги script для включения файлов разных модулей, и все работает нормально.

Мой вопрос:

1/ Почему система RequireJS лучше, чем эта система с несколькими тегами script?

С моим текущим подходом RequireJS:

define(['jquery'], function($) {

    var myModule = (function(my, $, undefined) {
        'use strict';

        var m_privateMembers;
        var m_stuff = new my.Pear({color:"green"});

        //---------------------------------------

        function privateFunctions(args) {
        }

        //-----------------------------------

        my.publicFunctions = function(args) {
        };

        return my;
    })(myModule || {}, $);

    return myModule;
});

2/ Как я могу перейти на модули RequireJS и сохранить одноэлементный шаблон, который мои фактические модули предоставляют со встроенными подклассами?

очевидно, есть несколько проблем:

2.1/ ​​*m_stuff не может создать экземпляр my.Pear, и я не знаю, как разделить модули на несколько файлов с помощью require ?*

2.2/ Если у меня есть два других модуля, которые оба зависят от myModule, будет ли переменная myModule var одним и тем же экземпляром в этих модулях (поскольку myModule больше не находится в глобальной области видимости)?

изменить: эта краткая схема иллюстрирует, что мне нужно сделать, в гораздо более сложной структуре:

схема


person Typedef    schedule 20.11.2013    source источник


Ответы (1)


Почему система RequireJS лучше, чем эта система с несколькими тегами script?

Я не буду вдаваться в подробности этого, но просто взглянув на существующую настройку модуля, вы увидите, что AMD сведет на нет необходимость в явном порядке сценариев и назначении вещей пространствам имен. Инструмент сборки RequireJS также позаботится о подготовке ваших скриптов к производству.

Вы можете прочитать больше

Как я могу перейти на модули RequireJS и сохранить одноэлементный шаблон, который мои фактические модули предоставляют со встроенными подклассами?

Давайте рассмотрим это на примере фруктов и груш.

При использовании require или define вы уже создаете замыкание, которое будет инкапсулировать всю вашу логику, поэтому нет необходимости создавать еще одно внутри. Будь проще.

// Fruit.js
define(['jquery'], function($) {
    'use strict';

    var Fruit = Object.makeSubclass();

    Fruit.prototype._init = function() {

    };

    Fruit.prototype.someClassFunction = function() {

    };

    return Fruit;
});

// Pear.js
define(['jquery', 'path/to/Fruit'], function($, Fruit) {
    'use strict';

    var Pear = Fruit.makeSubclass();

    Pear.prototype._init = function(args) {
        this.m_someClassMember = args;
    };

    Pear.prototype.someClassFunction = function() {

    };

    return Pear;
});

Я не знаю, как разбить модули на несколько файлов с помощью require?

По сути, просто разбейте свои «классы» или модули на отдельные модули AMD и явно определите зависимости, где это необходимо. Из приведенного выше примера видно, как Pear будет использовать модуль Fruit.

Если у меня есть два других модуля, которые оба зависят от myModule, будет ли переменная myModule одним и тем же экземпляром в этом модуле (поскольку myModule больше не находится в глобальной области видимости)?

После того, как вы один раз потребовали модуль и он был загружен, любые другие ссылки на него из других модулей получат тот же самый экземпляр. По этой причине часто рекомендуется, чтобы ваш модуль возвращал конструктор и позволял другим модулям создавать его экземпляры, где это необходимо.

person Simon Smith    schedule 21.11.2013
comment
Теперь это более ясно для меня, последнее, что я еще не совсем понимаю, это правильно ли я использовал одну и ту же возвращаемую переменную в своих модулях, чтобы обернуть их в общее пространство имен, но, похоже, это работает нормально. - person Typedef; 21.11.2013
comment
Нет необходимости использовать пространство имен с AMD. Идея состоит в том, чтобы сохранить все, что содержится в модулях, которые не относятся к глобальной области видимости. - person Simon Smith; 21.11.2013
comment
Если я работаю над фреймворком с несколькими большими приложениями, я обычно разбиваю их на коллекции или библиотеки модулей. Я не могу иметь сотни модулей в одной и той же плоской логической иерархии (или должен?). Набор модулей будет обрабатывать логику Fruit, другой будет обрабатывать совершенно другие задачи, такие как обмен сообщениями вне приложения и т. д. Мне также нужно повторно использовать часть модулей в других приложениях, например, в библиотеке обмена сообщениями. На самом деле то, что мне нужно, больше похоже на пространство имен C++, с плагином Singleton в каждой из моих библиотек и, конечно же, со всеми модулями моей библиотеки, используемыми моим плагином lib и/или другими модулями libs. - person Typedef; 21.11.2013
comment
Вы можете (и должны) группировать свои модули в структуру каталогов. Это позволит организовать ту же организацию, что и пространства имен. - person Simon Smith; 21.11.2013