Backbone.js 需要 RequireJS "shim" 吗?

Are RequireJS "shim" needed for Backbone.js?

Backbone.js 和 Underscore.js 的最新版本似乎支持 AMD。

所以我假设不再需要"shim" require.js 配置中的这些库是否正确?

正如@ggozad 提到的:

Well, if underscore is already loaded and available, you do not need the shim at all. Backbone will happily load. If not, it's probably because underscore is not actually loaded.

It sounds however wrong to be only partially using require.js, you might as well AMD-load them all.

我想这可以解释为什么您不需要使用 require.js

加载它

是的,你是对的,不需要垫片。而且它很容易测试,这里是最简单的设置:

requirejs.config({
    /**
     * Paths to lib dependencies.
     *
     * Use non-minified files where possible as they will be minified (and
     * optimized via uglify) on release build (r.js)
     */
    paths: {
        "jquery": "libs/jquery/dist/jquery",
        "underscore": "libs/underscore/underscore",
        "backbone": "libs/backbone/backbone",
    },

    deps: ["app"] // starts the app
});

并确保它有效并且不是使用的全局下划线:

// I'm using Underscore as to avoid conflicting with the global _
// but you could use _ as the name for the local variable as well.
define(['backbone', 'underscore'], function(Backbone, Underscore) {
    console.log("Backbone:", Backbone.VERSION)
    console.log("Local Underscore:", Underscore.VERSION);
    console.log("Global Underscore:", _.VERSION, _ === Underscore);
});

对于Backbone,在the source中明确表示默认支持AMD:

// Set up Backbone appropriately for the environment. Start with AMD.
if (typeof define === 'function' && define.amd) {
  define(['underscore', 'jquery', 'exports'], function(_, $, exports) {
    // Export global even in AMD case in case this script is loaded with
    // others that may still expect a global Backbone.
    root.Backbone = factory(root, exports, _, $);
  });

Underscore 是registering itself at the end:

// AMD registration happens at the end for compatibility with AMD loaders
// that may not enforce next-turn semantics on modules. Even though general
// practice for AMD registration is to be anonymous, underscore registers
// as a named module because, like jQuery, it is a base library that is
// popular enough to be bundled in a third party lib, but not be part of
// an AMD load request. Those cases could generate an error when an
// anonymous define() is called outside of a loader request.
if (typeof define === 'function' && define.amd) {
  define('underscore', [], function() {
    return _;
  });
}

jQuery 相同:

// Register as a named AMD module, since jQuery can be concatenated with other
// files that may use define, but not via a proper concatenation script that
// understands anonymous AMD modules. A named AMD is safest and most robust
// way to register. Lowercase jquery is used because AMD module names are
// derived from file names, and jQuery is normally delivered in a lowercase
// file name. Do this after creating the global so that if an AMD module wants
// to call noConflict to hide this version of jQuery, it will work.

// Note that for maximum portability, libraries that are not jQuery should
// declare themselves as anonymous modules, and avoid setting a global if an
// AMD loader is present. jQuery is a special case. For more information, see
// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon

if ( typeof define === "function" && define.amd ) {
    define( "jquery", [], function() {
        return jQuery;
    } );
}