RequireJS - 垫片中"exports"属性的目的是什么

Nar*_*esh 49 requirejs

垫片中"出口"物业的目的是什么?真的需要吗?

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

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

define(['backbone'], function (Backbone) {
  return Backbone.Model.extend({});
});
Run Code Online (Sandbox Code Playgroud)

Sim*_*ith 35

如果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({});
});
Run Code Online (Sandbox Code Playgroud)

为了给出一些上下文,我将使用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)));
Run Code Online (Sandbox Code Playgroud)

关键是当你要求一个模块时,给RequireJS一些东西返回给你,它会确保在这之前先加载.对于优化器,它只是简单地嵌入库.

  • 谢谢西蒙.我不是在问为什么使用垫片,而是为什么在垫片内需要"出口"属性?但是,您的回答给了我一个线索,即"exports"用于标识非AMD模块引入的全局.现在我再次阅读文档,他们说:"一旦加载,使用全局'Backbone'作为模块值".使用"Backbone"作为函数参数只是给出了对该模块的本地引用. (22认同)

Ian*_*ang 29

如果您不使用"导出" Backbone,那么您无法将模块中的语言环境引用获取到backbone.js中定义的Backbone(window.Backbone).

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


require(['bbn'], function(localBackbone) {
  //localBackbone undefined.
  console.log('localBackbone:,' localBackbone);
});
Run Code Online (Sandbox Code Playgroud)

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

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

function getGlobal(value) {
        if (!value) {
            return value;
        }
        var g = global;
        each(value.split('.'), function (part) {
            g = g[part];
        });
        return g;
    }
Run Code Online (Sandbox Code Playgroud)

  • 接受的答案甚至没有回答这个问题!@Ian Jiang的回答更好! (5认同)