使用 RequireJS 加载 Backbone 和 Underscore

IT技术 javascript backbone.js underscore.js requirejs
2021-01-18 04:15:44

我正在尝试使用 RequireJS 加载 Backbone 和 Underscore(以及 jQuery)。使用最新版本的 Backbone 和 Underscore,这似乎有点棘手。一方面,Underscore 自动将自己注册为一个module,但 Backbone 假设 Underscore 是全局可用的。我还应该注意到,Backbone 似乎没有将自己注册为一个module,这使得它与其他库不一致。这是我能想到的最好的 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现在使用新shim配置更好地处理非 AMD module,例如 Backbone 和 Underscore

shim配置使用起来很简单:(1) 声明依赖项 ( deps),如果有的话,(可能来自paths配置,也可能是有效路径本身)。(2)(可选)从您正在填充的文件中指定全局变量名称,该名称应该导出到需要它的module函数中。(如果您不指定导出,那么您只需要使用全局,因为什么都不会传递到您的 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 位于与此“main”代码相同的目录中的名为“jquery.js”、“backbone.js”和“underscore.js”的文件中(这成为 require 的 baseURL )。如果不是这种情况,您将需要使用路径配置

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

请注意,垫片配置与该示例项目兼容,可用于添加其他非 AMD 库。
2021-03-14 04:15:44
这个答案中的方法看起来很有希望,但对我不起作用。我改用了gist.github.com/2517531,效果很好。
2021-03-25 04:15:44
只是想我会提到这确实是要走的路,希望我能给 +50 票以使其成为#1 的答案。
2021-03-29 04:15:44
如果我理解正确的话,亨利,你是在问 $ 插件是否需要垫片。不是,如果您使用来自该示例项目的组合 require-jquery.js 文件。那是因为使用组合文件,jquery 会与 require 同步加载,因此当您尝试在任何module中使用任何 $ plugins 时,jquery 可以保证加载。在这种情况下,当您想使用 $ plugins 时,您可以将它们包含在您的依赖项列表中,就像它们是 AMD 一样,即使它们不是。这绝对是规则的一个例外,一般来说,任何非 AMD module都需要垫片。
2021-04-03 04:15:44
这段代码应该与Sample RequireJS 2.0.1 + jQuery 1.7.2 project requirejs.org/docs/download.html#samplejquery一起使用吗?
2021-04-13 04:15:44

更新:从 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();
    });
});

module已正确注册,无需订单插件:

// 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 糖,你也可以这样写:

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"
        }
    ]
})
很好的答案@Riebel!这对我真的很有用。顺便说一句,我还建议您看一下volo它是由 jrburke(requirejs 的创建者)创建的一个库,用于从 github 检索依赖项。例如,检索下划线的 amd 版本只需键入:volo add underscore
2021-03-20 04:15:44
+1 准确、有效且更新的答案+示例。干得好,里贝尔,你帮助了我,我相信其他人,很多。
2021-03-31 04:15:44
这正是我正在寻找的。谢谢!很好的详细答案。它现在就像你描述的那样运行。
2021-04-12 04:15:44
在原始帖子发布后很长时间保持更新的超级奖金。
2021-04-12 04:15:44

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

好消息,Underscore 1.6.0 现在支持 requirejs 定义!!!

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

只需加载它

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

我直接写下来,你可以在requirejs.org上阅读说明,你可以将下面的代码作为日常使用的片段;(ps 我使用 yeoman)(由于更新了很多东西,我在 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();
});

应用程序.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;
});

我希望我有用。!

比你知道的更有用。这正是我试图在我的项目 bower_components 和所有项目上构建的内容。谢谢@STEEL
2021-04-10 04:15:44