Используете модуль javascript, не совместимый с AMD, с require.js?

Я использую require.js для организации своего приложения на базе Backbone.js.

Я пытаюсь выяснить, как правильно использовать стороннюю библиотеку javascript, которая несовместима с AMD с require.js.

Библиотека, о которой идет речь, называется backbone-tastypie. js. По сути, библиотека занимается исправлением некоторых методов-прототипов Backbone, чтобы обеспечить более простую поддержку среды TastyPie Django REST. Он делает это, напрямую манипулируя объектом Backbone в глобальном пространстве имен.

Однако, поскольку я использую Backbone.js в качестве модуля require.js, он недоступен, когда эта библиотека пытается получить к нему доступ.

Как я могу импортировать этот backbone-tastypie в рамках Backbone?


person erikcw    schedule 30.12.2011    source источник


Ответы (3)


ОБНОВЛЕНИЕ: я разветвил совместимую с AMD backbone-tastypie под названием backbone-tastypie- доп.

Хотя решение Сандера будет работать, немного раздражает выполнять все вложенные требования каждый раз, когда вам нужна магистраль.

backbone-tastypie — это так называемый «традиционный сценарий». Вы можете решить проблему 4 способами.

  1. Обеспечьте совместимость с магистральной сетью AMD самостоятельно. Вы можете сделать это одним из двух способов. Вариант 1 — никогда не включать backbone напрямую — только backbone-tastypie. Затем измените фаворитный файл backbone, чтобы убедиться, что он необходим.

    var root = this;
    var Backbone = root.Backbone;
    if (!Backbone && (typeof require !== 'undefined')) Backbone = require('backbone').Backbone;
    

    Однако это не очень хорошо, потому что, по сути, он начнет загрузку backbone после того, как загрузится backbone-tastypie (синхронно). Это также не дает requirejs полного понимания того, как связаны эти модули, и в этом суть, верно? Итак, давайте обернем backbone-tastypie в функцию define():

    (function (factory) {
            if (typeof define === 'function' && define.amd) {
                    // AMD. Register as an anonymous module.
                    define(['backbone'], factory);
            } else {
                    // RequireJS isn't being used. Assume backbone is loaded in <script> tags
                    factory(Backbone);
            }
    }(function (Backbone) {
            //Backbone-tastypie contents
    }));
    

    Это, безусловно, лучший вариант из всего, что есть в этом ответе. RequireJS знает о зависимостях и может их разрешать, загружать и правильно оценивать. Стоит отметить, что Backbone сам загружает подчеркивание, используя опцию 1, и не определяет себя как модуль, что довольно плохо. Вы можете получить оптимизированную для AMD версию backbone прямо здесь. Предположим, вы используете эту версию AMD. теперь вы можете пойти дальше и потребовать backbone-tastypie в своем приложении (либо потребовав его в функции define(), либо в фактической функции require()). Вам также не нужно включать основу или подчеркивание, так как эти зависимости разрешаются с помощью requirejs.

  2. Используйте плагин для заказа require.js. Это заставляет вещи загружаться по порядку (в некоторых отношениях все еще асинхронно, поскольку они загружаются всякий раз, но оцениваются в правильном порядке).

    require(["order!backbone.js", "order!backbone-tastypie.js"], function () {
         //Your code
    });
    
  3. Поместите backbone.js в приоритетную конфигурацию. Это заставляет магистраль и ее зависимости всегда загружаться первыми, несмотря ни на что.

  4. Добавьте backbone-tastypie к тому же файлу, что и backbone.js. Каждый раз, когда загружается магистраль, загружается и магистраль. Хаки? да. Но это очень похоже на рекомендуемый способ использования jquery с requireJS (плагины jquery требуют, чтобы jquery был загружен - так же, как для backbone-tastypie требуется загрузка backbone).

person Adam Thomas    schedule 31.12.2011

Следующее должно работать с RequireJS 2.1.0+, если вы правильно настроили пути.

require.config({
  shim: {
    'underscore': {
      exports: '_'
    },
    'backbone': {
      deps: ['underscore','jquery'],
      exports: 'Backbone'
    },
    'backbone-tastypie': {
      deps: ['backbone']
    }
  }
);
person mike.pj    schedule 21.02.2013

вы можете обернуть свое требование другим требованием, плагин будет загружен первым, а затем вы можете сделать свое приложение.

require(["myCustomTastyPiePlugin.js"], function () {
    //This callback is called after the one script finish loading.

    require(["one.js", "two.js", "three.js"], function () {
        //This callback is called after the three scripts finish loading.

        // all your code goes here...

    });
});
person Sander    schedule 30.12.2011
comment
Я все еще изучаю AMD, но можно ли поместить этот вложенный оператор require в отдельный скрипт и вернуть соответствующие объекты, объединенные как члены составного объекта? Если бы это сработало, вам нужно было бы требовать только один файл, когда вам нужны оба. - person user4815162342; 17.07.2012
comment
вы можете сделать это да, вы можете добавить их в 1 требуемый блок, используя плагин заказа, чтобы убедиться, что они загружаются в правильном порядке. Впоследствии вы можете вернуть их как 2 свойства 1 нового модуля, который вы создали. Как и в моем примере, вы можете вернуть результат one.js, two.js и three.js в качестве свойств нового модуля. вернуть {один: один, два: два}; - person Sander; 17.07.2012
comment
Спасибо, я так и думал. - person user4815162342; 01.08.2012
comment
Расширение .js не требуется для Require. - person danwellman; 30.09.2014
comment
это не обязательно, но использовать его тоже не помешает. для новичков более очевидно, что он на самом деле делает. - person Sander; 01.10.2014