使用 RequreJS 加载主干和下划线

我尝试用 RequreJS 加载 Backbone 和 Underscore (以及 jQuery)。对于 Backbone 和 Underscore 的最新版本,这似乎有点棘手。首先,Underscore 自动将自己注册为模块,但 Backbone 假定 Underscore 是全局可用的。我还应该注意到,Backbone 似乎没有将自己注册为模块,这使得它与其他库不一致。这是我能想到的最好的主机:

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

还有更好的办法吗? 谢谢!

70232 次浏览

更新 : 从1.3.0版本开始。

您可以使用支持 AMD 的 Amdjs/Backbone 0.9.1Amdjs/下划线1.3.1分叉,它们来自 James Burke (RequreJS 的维护者)。

更多关于 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
}
};
});

关于优化器错误: 双重检查您的构建配置。我猜你的路径配置关闭了。如果你有一个 类似于 RequreJS 文档的目录设置,你可以使用:

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

使用新的 shim配置,RequreJS 2.X 现在可以更好地有机地处理非 AMD 模块,比如 Backbone & Underscore。

shim配置使用起来很简单: (1)声明依赖关系(deps) ,如果有的话(可能来自 paths配置,或者可能是有效路径本身)。(2)(可选)指定全局变量名称从文件你闪烁,这应该导出到您的模块功能,需要它。(如果没有指定导出,那么只需要使用全局,因为不会有任何内容传递到需求/定义函数中。)

下面是使用 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”的文件中,这些文件与这个“ main”代码位于同一个目录(它成为了需求的基 URL)。如果不是这种情况,您将需要使用 路径配置

我个人认为使用内置的 shim功能,不使用分叉版本的 Backbone & Underscore 的好处超过使用其他流行答案中推荐的 AMD 分叉的好处,但是无论哪种方式都可以工作。

好消息,下划线1.6.0现在支持必要条件定义! ! !

下面的版本需要 shims,或者需要 underscore.js,然后盲目地希望“ _”全局变量没有被破坏(公平地说,这是一个公平的赌注)

只要把它装进去

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

我会直接写下来,你可以阅读必备的 js.org 上的解释,你可以使用下面的代码作为你日常使用的片段; (附注: 我使用约曼)(因为很多东西更新,我张贴到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 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;
});

我希望我能帮上忙!

作为参考,在1.1.1(~ Feb’13)版本中,Backbone 也是 注册为 AMD 模块。它将与需求一起工作,而不需要使用它的垫片配置。(James Burke 的 Amdjs 叉子自1.1.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();
});