Javascript 使用 RequireJS 加载 Backbone 和 Underscore
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8131265/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Loading Backbone and Underscore using RequireJS
提问by Aaronius
I'm trying to load Backbone and Underscore (as well as jQuery) with RequireJS. With the latest versions of Backbone and Underscore, it seems kind of tricky. For one, Underscore automatically registers itself as a module, but Backbone assumes Underscore is available globally. I should also note that Backbone doesn't seem to register itself as a module which makes it kind of inconsistent with the other libs. This is the best main.js I could come up with that works:
我正在尝试使用 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();
})
});
I should mention that, while it works, the optimizer chokes on it. I receive the following:
我应该提到的是,虽然它有效,但优化器会窒息。我收到以下信息:
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
Is there a better way of handling this? Thanks!
有没有更好的方法来处理这个问题?谢谢!
回答by Ben Roberts
RequireJS 2.Xnow organically addresses non-AMD modules such as Backbone & Underscore much better, using the new shim
configuration.
RequireJS 2.X现在使用新shim
配置更好地处理非 AMD 模块,例如 Backbone 和 Underscore 。
The shim
configuration is simple to use: (1) one states the dependencies (deps
), if any, (which may be from the paths
configuration, or may be valid paths themselves). (2) (optionally) specify the global variable name from the file you're shimming, which should be exported to your module functions that require it. (If you don't specify the exports, then you'll need to just use the global, as nothing will get passed into your require/define functions.)
该shim
配置使用起来很简单:(1) 声明依赖项 ( deps
),如果有的话,(可能来自paths
配置,也可能是有效路径本身)。(2)(可选)从您正在填充的文件中指定全局变量名称,该名称应导出到需要它的模块函数中。(如果您不指定导出,那么您只需要使用全局,因为什么都不会传递到您的 require/define 函数中。)
Here is a simple example usage of shim
to load Backbone. It also adds an export for underscore, even though it doesn't have any dependencies.
这是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
});
Note:this simplified code assumes that jquery, backbone and underscore are in files named "jquery.js", "backbone.js" and "underscore.js" in the same directory as this "main" code (which becomes the baseURL for require). If this isn't the case, you'll need to use a paths config.
注意:此简化代码假设 jquery、backbone 和 underscore 位于与此“main”代码相同的目录中的名为“jquery.js”、“backbone.js”和“underscore.js”的文件中(这成为 require 的 baseURL )。如果不是这种情况,您将需要使用路径配置。
I personally think with the built-in shim
functionality, the advantages of not using a forked version of Backbone & Underscore outweigh the benefits of using the AMD fork recommended in the other popular answer, but either way works.
我个人认为,对于内置shim
功能,不使用 Backbone & Underscore 分叉版本的优势超过了使用其他流行答案中推荐的 AMD 分叉的好处,但无论哪种方式都有效。
回答by Riebel
Update: As of version 1.3.0 Underscore removed AMD (RequireJS) support.
更新:从 1.3.0 版起,Underscore 删除了 AMD (RequireJS) 支持。
You can use the amdjs/Backbone 0.9.1and the amdjs/Underscore 1.3.1fork with AMD support from James Burke (the maintainer of RequireJS).
您可以使用amdjs/Backbone 0.9.1和amdjs/Underscore 1.3.1fork,并获得 James Burke(RequireJS 的维护者)的 AMD 支持。
More info about AMD support for Underscore and Backbone.
有关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();
});
});
The modules are properly registered and there is no need for the order plugin:
模块已正确注册,无需订单插件:
// app.js
define([
'jquery',
'underscore',
'backbone'
], function($, _, Backbone){
return {
initialize: function(){
// you can use $, _ or Backbone here
}
};
});
Underscore is actually optional, because Backbone now gets its dependencies on its own:
Underscore 实际上是可选的,因为 Backbone 现在可以自己获取依赖项:
// app.js
define(['jquery', 'backbone'], function($, Backbone){
return {
initialize: function(){
// you can use $ and Backbone here with
// dependencies loaded i.e. Underscore
}
};
});
With some AMD sugaryou could also write it like this:
用一些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
}
};
});
Regarding the optimizer error: doublecheck your build configuration. I assume your path configuration is off. If you have a directory setup similar to the RequireJS Docsyou can use:
关于优化器错误:仔细检查您的构建配置。我假设您的路径配置已关闭。如果您有一个类似于 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"
}
]
})
回答by biril
For reference, as of version 1.1.1 (~Feb '13), Backbone also registers itself as an AMD module. It will work with requirejs without the need to use its shim config. (James Burke's amdjs forkalso hasn't been updated since 1.1.0)
作为参考,从 1.1.1 版(~2013 年 2 月)开始,Backbone 也将自己注册为 AMD 模块。它将与 requirejs 一起使用,而无需使用其 shim 配置。(James Burke 的 amdjs fork也从 1.1.0 开始没有更新)
回答by aqm
Good news, Underscore 1.6.0 now supports requirejs define !!!
好消息,Underscore 1.6.0 现在支持 requirejs 定义!!!
versions below this require shims, or requiring underscore.js then blindly hoping that the "_" global variable hasn;t been smashed (which to be fair is a fair bet)
下面的版本需要垫片,或者需要 underscore.js 然后盲目地希望“_”全局变量没有被粉碎(公平地说,这是一个公平的赌注)
simply load it in by
只需加载它
requirejs.config({
paths: {
"underscore": "PATH/underscore-1.6.0.min",
}
});
回答by STEEL
I will write down directly, you can read the explaination on requirejs.org, you could use below code as a snippet for your everyday use; (p.s. i use yeoman) (since many things updated, im posting this as of Feb 2014.)
我直接写下来,你可以在requirejs.org上阅读说明,你可以将下面的代码作为日常使用的片段;(ps 我使用 yeoman)(由于更新了很多东西,我在 2014 年 2 月发布了这个。)
Make sure you included script in your index.html
确保在 index.html 中包含脚本
<!-- build:js({app,.tmp}) scripts/main.js -->
<script data-main="scripts/main" src="bower_components/requirejs/require.js"></script>
<!-- endbuild -->
Then, in main.js
然后,在 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
应用程序.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;
});
I hope I was useful.!
我希望我有用。!
回答by Sumesh TG
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();
});