Загрузка базовой линии и поддерева с использованием RequireJS

Я пытаюсь загрузить Backbone и Underscore (а также jQuery) с RequireJS. С последними версиями Backbone и Underscore это кажется довольно сложным. Во-первых, Underscore автоматически регистрируется как модуль, но Backbone предполагает, что Underscore доступен во всем мире. Я также должен отметить, что Backbone, похоже, не регистрируется как модуль, который делает его несовместимым с другими libs. Это лучший 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 been defined from within Underscore and set it as a global variable for
    // Backbone sake.  Hopefully Backbone will soon be able to use the Underscore module directly instead of
    // assuming it 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

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

Ответ 1

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

Конфигурация shim проста в использовании: (1) заявляется зависимость (deps), если она есть, (которая может быть из конфигурации paths или может быть действительными путями). (2) (необязательно) укажите имя глобальной переменной из файла, который вы shimming, который должен быть экспортирован в требуемые ему функции модуля. (Если вы не укажете экспорт, тогда вам нужно просто использовать глобальный, поскольку ничто не будет передано в ваши функции 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, backbone и подчеркивание находятся в файлах с именем "jquery.js", "backbone.js" и "underscore.js" в том же каталоге, что и этот "основной" код ( который становится базой для запросов). Если это не так, вам нужно будет использовать конфигурацию путей .

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

Ответ 2

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

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

Подробнее о поддержка AMD для подделок и магистрали.

// 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, вы можете использовать:

// 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"
        }
    ]
})

Ответ 4

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

Убедитесь, что вы включили script в свой index.html

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

Затем в main.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;
});

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

Ответ 5

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

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

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

  requirejs.config({
    paths: {
        "underscore": "PATH/underscore-1.6.0.min",
    }
  });