Загрузка Backbone и Underscore с использованием RequireJS
Я пытаюсь загрузить 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 ответов
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, backbone и underscore находятся в файлах с именами "jquery.js", "backbone.js" и "underscore.js" в том же каталоге, что и этот "основной" код (который становится baseURL для require).Если это не так, вам нужно использовать конфигурацию путей.
Лично я думаю со встроенным shim
функциональность, преимущества отсутствия разветвленной версии Backbone & Underscore перевешивают преимущества использования AMD-форка, рекомендованного в другом популярном ответе, но в любом случае это работает.
Обновление: Начиная с версии 1.3.0 Underscore удалена поддержка AMD (RequireJS).
Вы можете использовать amdjs/Backbone 0.9.1 и вилку amdjs/Underscore 1.3.1 с поддержкой AMD от James Burke (сопровождающего 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"
}
]
})
Для справки, начиная с версии 1.1.1 (~ февраль '13), Backbone также регистрируется как модуль AMD. Он будет работать с requirejs без необходимости использовать его конфигурацию shim. ( Форк amdjs Джеймса Бёрка также не обновлялся с 1.1.0)
Хорошая новость: Underscore 1.6.0 теперь поддерживает requirejs define!!!
версии ниже этого требуют шиммы, или требуют underscore.js, затем вслепую надеясь, что глобальная переменная "_" не была разбита (что справедливо, будет честной ставкой)
просто загрузите его
requirejs.config({
paths: {
"underscore": "PATH/underscore-1.6.0.min",
}
});
Я напишу прямо, вы можете прочитать объяснение на 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 -->
Затем в 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;
});
Я надеюсь, что был полезен.
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();
});