使用RequireJS加载Backbone和Underscore

Aar*_*ius 172 javascript requirejs backbone.js underscore.js

我正在尝试使用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();
    })
});
Run Code Online (Sandbox Code Playgroud)

我应该提一下,虽然它有效,但优化器会对它产生影响.我收到以下内容:

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
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法来处理这个?谢谢!

Ben*_*rts 293

RequireJS 2.X现在使用新shim配置更好地有效地处理Backbone和Underscore等非AMD模块.

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

});
Run Code Online (Sandbox Code Playgroud)

注意:这个简化的代码假定jquery,backbone和underscore在名为"jquery.js","backbone.js"和"underscore.js"的文件中与此"main"代码在同一目录中(它成为require的baseURL) ).如果不是这种情况,则需要使用路径配置.

我个人认为使用内置shim功能,不使用分叉版本的Backbone和Underscore的优势超过了使用其他流行答案推荐的AMD分叉的好处,但两种方式都有效.

  • 我想我会提到这真的是要走的路,希望我可以给予+50支票,让它成为#1答案. (11认同)

Rie*_*bel 171

更新:从版本1.3.0开始,Underscore删除了AMD(RequireJS)支持.

您可以使用amdjs/Backbone 0.9.1amdjs/Underscore 1.3.1 fork以及James Burke(RequireJS的维护者)的AMD支持.

有关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();
    });
});
Run Code Online (Sandbox Code Playgroud)

模块已正确注册,无需订购插件:

// app.js
define([
    'jquery', 
    'underscore',
    'backbone'
], function($, _, Backbone){
    return {
        initialize: function(){
            // you can use $, _ or Backbone here
        }
    };
});
Run Code Online (Sandbox Code Playgroud)

Underscore实际上是可选的,因为Backbone现在可以自己获取它的依赖:

// app.js
define(['jquery', 'backbone'], function($, Backbone){
    return {
        initialize: function(){
            // you can use $ and Backbone here with
            // dependencies loaded i.e. Underscore
        }
    };
});
Run Code Online (Sandbox Code Playgroud)

有了一些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
        }
    };
});
Run Code Online (Sandbox Code Playgroud)

关于优化程序错误:双击您的构建配置.我假设您的路径配置已关闭.如果您有一个类似于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"
        }
    ]
})
Run Code Online (Sandbox Code Playgroud)

  • 在原始帖子之后保持此更新的超级奖励. (22认同)
  • 这正是我想要的.谢谢!非常详细的答案.它现在正如你所描述的那样运行. (4认同)
  • +1准确,工作和更新的答案+示例.优秀的工作Riebel,你帮助了我,我很确定其他人. (2认同)

bir*_*ril 5

作为参考,从版本1.1.1(〜2013年2月)开始,Backbone还将自己注册为AMD模块.它将与requirejs一起使用,而无需使用其shim配置.(James Burke的amdjs fork自1.1.0以来也没有更新)