将requireJS模块暴露到全局命名空间的正确方法是什么?

9

我希望将一个Javascript API作为一个独立的库暴露出来,而不会污染全局命名空间。根据http://requirejs.org/docs/faq-advanced.html,我已经创建了包装器,以便不会污染他们自己的requireJS。我已经简化了目前的内容,但是我不确定这是否是正确的方式,或者我是否应该采用其他方式。

var MyApi = MyApi || {};
var MyApiRequireJS = (function() {
  // require.js pasted here
  return {requirejs: requirejs, require: require, define: define};
})();

(function(require, define, requirejs) {
  require.config({
    baseUrl: 'js/scripts',
    waitSeconds: 30,
  });  

  define( 'myapi', ['jquery', 'underscore'],
    function($, _) {
      $.noConflict(true);
      _.noConflict();
      function api(method, args, callback) {
        // do stuff here
      }
      return {api: api};
    }
  );

  require( ['myapi'], function( myapi ) {
    MyApi = myapi;
  });
}(MyApiRequireJS.require, MyApiRequireJS.define, MyApiRequireJS.requirejs));

使用这个库的网站会包含一个脚本标签引用上面的代码,然后通过调用API来使用。

MyApi.api('some_remote_method', {foo: 'bar'}, function(result) {
  // handle the result
});

你是说你不想让requiredefine出现在全局命名空间中,但你愿意让MyApiMyApiRequireJS出现在全局命名空间中?我可以问一下原因吗? - Paul Grime
他们更有可能已经在全局命名空间中使用requiredefine,而不是MyApiMyApi不是我要使用的变量,只是为了简单起见使用了它)。同样,Facebook Connect API只会在全局命名空间中污染FB - Wing Lian
他们是使用 require 还是 define?你能找出来吗?如果不能,那也没有问题。如果你不知道他们的全局命名空间使用了什么,那么你就不能确定你定义的任何全局变量是否已经被使用了。 - Paul Grime
1个回答

0

我认为你试图通过将别人的问题变成你的问题来预测,但我不认为你真的可以合理地这样做。你链接到的页面旨在让已经命名为“require”或“define”的Javascript全局变量的人将RequireJS全局变量重命名为其他名称。它并不意味着创建两个独立解决依赖关系的RequireJS实例。

话虽如此,如果你真的想要最小化命名空间污染,那么你应该只公开一个名称——MyApi。编写一个包含你的私有RequireJS副本以及API代码的大型闭包,并仅返回你想要在API上公开的方法。

也许以两个版本提供你的API更加友好/简单,一个定义了requireJS模块,另一个没有requireJS依赖性。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接