Загрузка Backbone и Underscore с использованием RequireJS - PullRequest
172 голосов
/ 15 ноября 2011

Я пытаюсь загрузить Backbone и Underscore (а также jQuery) с RequireJS.С последними версиями Backbone и Underscore это выглядит довольно сложно.Например, Underscore автоматически регистрируется как модуль, но Backbone предполагает, что Underscore доступен во всем мире.Я также должен отметить, что Backbone, похоже, не регистрирует себя как модуль, что делает его несовместимым с другими библиотеками.Это лучший файл main.js, который я смог придумать, который работает:

require(
{
    paths: {
        'backbone': 'libs/backbone/backbone-require',
        'templates': '../templates'
    }
},
[
    // jQuery registers itself as a module.
    'http://cdnjs.cloudflare.com/ajax/libs/jquery/1.7/jquery.min.js',

    // Underscore registers itself as a module.
    'http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.2.1/underscore-min.js'
], function() {

    // These nested require() calls are just due to how Backbone is built.  Underscore basically says if require()
    // is available then it will automatically register an "underscore" module, but it won't register underscore
    // as a global "_".  However, Backbone expects Underscore to be a global variable.  To make this work, we require
    // the Underscore module after it's been defined from within Underscore and set it as a global variable for
    // Backbone's sake.  Hopefully Backbone will soon be able to use the Underscore module directly instead of
    // assuming it's global.
    require(['underscore'], function(_) {
        window._ = _;
    });

    require([
        'order!http://cdnjs.cloudflare.com/ajax/libs/backbone.js/0.5.3/backbone-min.js',
        'order!app'
    ], function(a, app) {
        app.initialize();
    })
});

Я должен отметить, что, пока он работает, оптимизатор подавляется им.Я получаю следующее:

Tracing dependencies for: main
js: "/home/httpd/aahardy/requirejs/r.js", line 7619: exception from uncaught JavaScript throw: Error: Error: Error evaluating module "undefined" at location "/home/httpd/aahardy/phoenix/trunk/ui/js/../../ui-build/js/underscore.js":
JavaException: java.io.FileNotFoundException: /home/httpd/aahardy/phoenix/trunk/ui/js/../../ui-build/js/underscore.js (No such file or directory)
fileName:/home/httpd/aahardy/phoenix/trunk/ui/js/../../ui-build/js/underscore.js
lineNumber: undefined
http://requirejs.org/docs/errors.html#defineerror
In module tree:
    main

Есть ли лучший способ справиться с этим?Спасибо!

Ответы [ 6 ]

293 голосов
/ 06 июня 2012

RequireJS 2.X теперь намного лучше органически обращается к модулям не-AMD, таким как Backbone & Underscore, используя новую конфигурацию shim.

Конфигурация shim проста в использовании: (1) устанавливаются зависимости (deps), если таковые имеются (которые могут быть из конфигурации paths или могут быть действительными путями),(2) (опционально) укажите имя глобальной переменной из файла, который вы используете, для экспорта в функции вашего модуля, которым это требуется.(Если вы не укажете экспорт, вам нужно будет просто использовать глобальный, так как ничто не будет передано в ваши функции require / define.)

Вот простой пример использования shimзагрузить Backbone.Он также добавляет экспорт для подчеркивания, даже если у него нет никаких зависимостей.

require.config({
  shim: {
    underscore: {
      exports: '_'
    },
    backbone: {
      deps: ["underscore", "jquery"],
      exports: "Backbone"
    }
  }
});

//the "main" function to bootstrap your code
require(['jquery', 'underscore', 'backbone'], function ($, _, Backbone) {   // or, you could use these deps in a separate module using define

});

Примечание: этот упрощенный код предполагает, что jquery, магистраль и подчеркивание находятся в файлах с именами "jquery.js", "backbone.js" и "underscore.js".msgstr "в том же каталоге, что и этот" основной "код (который становится baseURL для require).Если это не так, вам нужно использовать конфигурацию paths .

Я лично считаю, что благодаря встроенной функциональности shim преимуществ нетиспользование раздвоенной версии Backbone & Underscore перевешивает преимущества использования AMD-форка, рекомендованного в другом популярном ответе, но в любом случае работает.

171 голосов
/ 16 ноября 2011

Обновление : Начиная с версии 1.3.0 Подчеркнута удаленная поддержка AMD (RequireJS) .

Вы можете использовать amdjs / Backbone 0.9.1 и вилка amdjs / Underscore 1.3.1 с поддержкой AMD от Джеймса Бёрка (сопровождающего RequireJS).

Дополнительная информация о поддержке AMD для Underscore и Backbone .

// main.js using RequireJS 1.0.7
require.config({
    paths: {
        'jquery': 'libs/jquery/1.7.1/jquery',
        'underscore': 'libs/underscore/1.3.1-amdjs/underscore', // AMD support
        'backbone': 'libs/backbone/0.9.1-amdjs/backbone', // AMD support
        'templates': '../templates'
    }
});

require([
    'domReady', // optional, using RequireJS domReady plugin
    'app'
], function(domReady, app){
    domReady(function () {
        app.initialize();
    });
});

Модули правильно зарегистрированы и нет необходимости в плагине заказа:

// app.js
define([
    'jquery', 
    'underscore',
    'backbone'
], function($, _, Backbone){
    return {
        initialize: function(){
            // you can use $, _ or Backbone here
        }
    };
});

Подчеркивание фактически необязательно, потому что Backbone теперь получает свои зависимости самостоятельно:

// app.js
define(['jquery', 'backbone'], function($, Backbone){
    return {
        initialize: function(){
            // you can use $ and Backbone here with
            // dependencies loaded i.e. Underscore
        }
    };
});

С некоторыми AMD сахар вы также можете написать это так:

define(function(require) {
    var Backbone = require('backbone'),
        $ = require('jquery');

    return {
        initialize: function(){
            // you can use $ and Backbone here with
            // dependencies loaded i.e. Underscore
        }
    };
});

Относительно ошибки оптимизатора: перепроверьте конфигурацию сборки.Я предполагаю, что ваша конфигурация пути отключена.Если у вас есть каталог , похожий на RequireJS Docs , вы можете использовать:

// app.build.js
({
    appDir: "../",
    baseUrl: "js",
    dir: "../../ui-build",
    paths: {
        'jquery': 'libs/jquery/1.7.1/jquery',
        'underscore': 'libs/underscore/1.3.1-amdjs/underscore',
        'backbone': 'libs/backbone/0.9.1-amdjs/backbone',
        'templates': '../templates'
    }, 
    modules: [
        {
            name: "main"
        }
    ]
})
5 голосов
/ 16 августа 2014

Для справки, начиная с версии 1.1.1 (~ февраль '13), Backbone также регистрируется как модуль AMD .Он будет работать с requirejs без необходимости использовать его конфигурацию shim.( форк amdjs Джеймса Бёрка также не обновлялся с 1.1.0)

4 голосов
/ 28 февраля 2014

Я напишу прямо, вы можете прочитать объяснение на requirejs.org, вы можете использовать приведенный ниже код в качестве фрагмента для вашего повседневного использования;(ps я использую yeoman) (так как многие вещи обновлены, я публикую это по состоянию на февраль 2014 года.)

Убедитесь, что вы включили скрипт в ваш index.html

<!-- build:js({app,.tmp}) scripts/main.js -->
<script data-main="scripts/main" src="bower_components/requirejs/require.js"></script>
<!-- endbuild -->

Затем, в основном.js

require.config({
    shim: {
        'backbone': {
            deps: ['../bower_components/underscore/underscore.js', 'jquery'],
            exports: 'Backbone'
        }
    },

    paths: {
        jquery: '../bower_components/jquery/jquery',
        backbone: '../bower_components/backbone/backbone'
    }
});

require(['views/app'], function(AppView){
    new AppView();
});

app.js

/**
 * App View
 */
define(['backbone', 'router'], function(Backbone, MainRouter) {
    var AppView = Backbone.View.extend({
        el: 'body',

        initialize: function() {
            App.Router = new MainRouter();
            Backbone.history.start();
        }
    });

    return AppView;
});

Надеюсь, я был полезен.!

4 голосов
/ 12 февраля 2014

Хорошие новости, Underscore 1.6.0 теперь поддерживает requirejs define !!!

версии ниже этого требуют шиммы или требуют underscore.js, затем вслепую надеясь, что глобальная переменная "_" не разбита (что справедливо, это справедливая ставка)

просто загрузите его на

  requirejs.config({
    paths: {
        "underscore": "PATH/underscore-1.6.0.min",
    }
  });
0 голосов
/ 19 января 2018
require.config({
  waitSeconds: 500,
  paths: {
    jquery: "libs/jquery/jquery",
    jqueryCookie: "libs/jquery/jquery.cookie",
    .....
  },

  shim: {
    jqxcore: {
      export: "$",
      deps: ["jquery"]
    },
    jqxbuttons: {
      export: "$",
      deps: ["jquery", "jqxcore"]
    }
    ............
  }
});

require([
 <i> // Load our app module and pass it to our definition function</i>
  "app"
], function(App) {
  // The "app" dependency is passed in as "App"
  // Again, the other dependencies passed in are not "AMD" therefore don't pass a parameter to this function
  App.initialize();
});
...