我正在尝试使用RequireJS加载Backbone和Underscore(以及jQuery)。使用最新版本的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
有没有更好的方法来处理这个?谢谢!
答案 0 :(得分:293)
RequireJS 2.X现在有机地解决了非AMD模块,例如Backbone&使用新的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”的文件中作为这个“主要”代码(它成为require的baseURL)。如果不是这种情况,则需要使用paths config。
我个人认为内置shim
功能,不使用分叉版Backbone& Underscore超过了使用其他流行答案推荐的AMD分叉的好处,但两种方式都有效。
答案 1 :(得分:171)
更新:从版本1.3.0 Underscore removed AMD (RequireJS) support开始。
您可以使用amdjs/Backbone 0.9.1和amdjs/Underscore 1.3.1分支与James Burke(RequireJS的维护者)的AMD支持。
有关AMD support for Underscore and 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
}
};
});
Underscore实际上是可选的,因为Backbone现在可以自己获得依赖:
// app.js
define(['jquery', 'backbone'], function($, Backbone){
return {
initialize: function(){
// you can use $ and Backbone here with
// dependencies loaded i.e. Underscore
}
};
});
对于某些AMD sugar,您也可以这样写:
define(function(require) {
var Backbone = require('backbone'),
$ = require('jquery');
return {
initialize: function(){
// you can use $ and Backbone here with
// dependencies loaded i.e. Underscore
}
};
});
关于优化程序错误:双击您的构建配置。我假设您的路径配置已关闭。如果您有directory setup similar to the 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"
}
]
})
答案 2 :(得分:5)
作为参考,从版本1.1.1(〜Feb' 13)开始,Backbone也registers itself as an AMD module。它将与requirejs一起使用,而无需使用其shim配置。 (James Burke's amdjs fork自1.1.0以来也没有更新
答案 3 :(得分:4)
好消息,Underscore 1.6.0现在支持requirejs define !!!
以下版本需要垫片,或者需要使用underscore.js然后盲目地希望“_”全局变量没有被破坏(这是公平的赌注)
只需通过
加载即可 requirejs.config({
paths: {
"underscore": "PATH/underscore-1.6.0.min",
}
});
答案 4 :(得分:4)
我会直接写下来,你可以阅读requirejs.org上的解释,你可以使用下面的代码作为你日常使用的片段; (p.s.我使用自耕农)(因为很多事情已经更新,我发布截至2014年2月。)
确保在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 :(得分:0)
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();
});