50

下面 shim 中的“exports”属性的目的是什么?真的需要吗?

requirejs.config({
    shim: {
        'backbone': {
            deps: ['underscore', 'jquery'],
            exports: 'Backbone'
        }
    }
});

我问是因为这似乎是多余的 - 当模块包含在依赖项列表中时,我们将再次指定导出的名称作为函数参数:

define(['backbone'], function (Backbone) {
  return Backbone.Model.extend({});
});
4

4 回答 4

36

如果shim在您的示例中未使用,则Backbone作为参数传入的对象将未定义,因为 Backbone 不符合 AMD 标准,并且不会返回对象供 RequireJS 使用。

define(['backbone'], function (Backbone) {
  // No shim? Then Backbone here is undefined as it may
  // load out of order and you'll get an error when
  // trying to use Model
  return Backbone.Model.extend({});
});

为了提供一些上下文,我将使用 r.js 优化器吐出的代码,但我将在此示例中对其进行简化。它通过阅读优化器产生的内容帮助我理解了它的要点。

带垫片的 Backbone 有点像这样:

// Create self invoked function with the global 'this'
// passed in. Here it would be window
define("backbone", (function (global) {
    // When user requires the 'backbone' module
    // as a dependency, simply return them window.Backbone
    // so that properites can be accessed
    return function () {
        return global.Backbone;
    };
}(this)));

关键是当你请求一个模块时,给 RequireJS 一些东西来返回给你,它会确保在这样做之前先加载它。在优化器的情况下,它将简单地预先嵌入库。

于 2012-12-31T03:04:15.963 回答
29

如果您不使用“export” Backbone,那么您将无法在模块中获取到 Backbone(window.Backbone) 的语言环境引用,该引用在主干.js 中定义。

//without export Backbone
shim : {
  'bbn':{
        //exports:'Backbone',
        deps:['underscore']
    },
    'underscore': {
        exports: '_'
    }
};


require(['bbn'], function(localBackbone) {
  //localBackbone undefined.
  console.log('localBackbone:,' localBackbone);
});

RequireJs 解释如下:

//RequireJS will use the shim config to properly load 'backbone' and give a local
//reference to this module. The global Backbone will still exist on
//the page too.
define(['backbone'], function (Backbone) {
  return Backbone.Model.extend({});
});

RequireJS 将使用 shim 配置来获取全局 Backbone

function getGlobal(value) {
        if (!value) {
            return value;
        }
        var g = global;
        each(value.split('.'), function (part) {
            g = g[part];
        });
        return g;
    }
于 2013-03-21T05:40:05.177 回答
2

另请注意,您可能希望在“导出”中使用插件的实际导出。例如,

requirejs.config({
    shim: {
        'jquery.colorize': {
            deps: ['jquery'],
            exports: 'jQuery.fn.colorize'
        },
        'jquery.scroll': {
            deps: ['jquery'],
            exports: 'jQuery.fn.scroll'
        },
        'backbone.layoutmanager': {
            deps: ['backbone']
            exports: 'Backbone.LayoutManager'
        },
        "jqueryui": {
            deps: ["jquery"],
            //This is because jQueryUI plugin exports many things, we would just 
            //have reference to main jQuery object. RequireJS will make sure to
            //have loaded jqueryui script.
            exports: "jQuery"  
        },
        "jstree": {
            deps: ["jquery", "jqueryui", "jquery.hotkeys", "jquery.cookie"],
            exports: "jQuery.fn.jstree"
        },
        "jquery.hotkeys": {
            deps: ["jquery"],
            exports: "jQuery"  //This plugins don't export object in jQuery.fn
        },
        "jquery.cookie": {
            deps: ["jquery"],
            exports: "jQuery" //This plugins don't export object in jQuery.fn
        }
    }
});

更多:https ://github.com/jrburke/requirejs/wiki/Upgrading-to-RequireJS-2.0#wiki-shim

于 2013-11-03T08:47:39.973 回答
1

Shim 导出是为了让 requirejs 知道如何处理非 AMD 模块。没有它,在模块启动时,define 块中的依赖项仍将被加载。它向 requirejs 发出信号,表明它已停止加载资源并且模块可以开始使用它。

至少,我是这么看的。

于 2012-12-30T22:51:38.697 回答