Javascript 使用不带导出的UMD来简单地增加依赖性是否合理?

Javascript 使用不带导出的UMD来简单地增加依赖性是否合理?,javascript,angularjs,amd,commonjs,umd,Javascript,Angularjs,Amd,Commonjs,Umd,我正在创建我的第一个AngularJS模块,用于开源发行版。我想用一种便于他人消费的方式来包装它 UMD项目为导出与AMD、CommonJS(或至少是Node)和浏览器全局兼容的JavaScript模块提供了一个解决方案: (function (root, factory) { if (typeof define === 'function' && define.amd) { define(['b'], factory); // AMD } else if (ty

我正在创建我的第一个AngularJS模块,用于开源发行版。我想用一种便于他人消费的方式来包装它

UMD项目为导出与AMD、CommonJS(或至少是Node)和浏览器全局兼容的JavaScript模块提供了一个解决方案:

(function (root, factory) {
  if (typeof define === 'function' && define.amd) {
    define(['b'], factory); // AMD
  } else if (typeof exports === 'object') {
    module.exports = factory(require('b')); // Node
  } else {
    root.returnExports = factory(root.b); // browser global (root is window)
  }
}(this, function (b) {
  // use b in some fashion
  return {}; // return a value to define the module export
}));
但是,由于AngularJS有自己的内部模块系统,注册模块只需在
angular
对象上调用一个方法即可,即
angular.module()
。因此,UMD模块不需要导出任何内容;它只需要在
angular
上进行操作。在前面的例子中,我认为应该是这样的:

(function (root, factory) {
  if (typeof define === 'function' && define.amd) {
    factory(require(['b'])); // AMD
  } else if (typeof exports === 'object') {
    factory(require('b')); // Node
  } else {
    factory(root.b); // browser global (root is window)
  }
}(this, function (b) {
  // use b in some fashion
}));
或者,针对我的情况:

(function (root, factory) {
  if (typeof define === 'function' && define.amd) {
    factory(require(['angular'])); // AMD
  } else if (typeof exports === 'object') {
    factory(require('angular')); // Node
  } else {
    factory(root.angular); // browser global (root is window)
  }
}(this, function (angular) {
  angular.module( ... );
}));

这没什么大不了的,还是违背了UMD的精神?我这样问是因为我找不到任何不导出任何内容的UMD模式。

作为angular插件,最好提供一个导出生成器的模块,这样人们就可以对“angular意味着什么”负责。例如,假设我正在使用angular的定制调试版本,但想使用您的代码:现在,我不能,因为您已经决定为我要求angular。这似乎是个好主意,但事实并非如此:

var myangular = require('debug-angular/ext/symbolised');
var yourmodule = require('yourmodule');
yourmodule.register(myangular);
现在我知道,作为开发人员,您的代码将使用我的angular,而不是现在加载两个不同版本的angular,以及由此产生的所有有趣的版本不匹配错误

因此,更好的umd工厂应该是:

(function (root, factory) {
  if (typeof define !== 'undefined' && define.amd) {
    define(['angular'] , function (angular) {
      factory(angular);
    });
  } else if (typeof module !== 'undefined' && module.exports) {
    module.exports = {
      register: function(angular) {
        factory(angular);
      }
    };
  } else {
    factory(root.angular); // browser global (root is window)
  }
}(this, function (angular) {
  angular.module( ... );
}));

我看不出使用这种模式有什么错。正如您可能已经发现的,Angular在现有模块系统中使用的不是很好,因为它使用自己的模块系统,但是模块不必导出任何东西。项目的主模块多久导出一次?通常,它只是得到依赖项

如果您正在寻找一个类似的例子,那么可以看看jQuery mousewheel插件,它使用UMD,但依赖于jQuery

摘自
jquery.mouseweel.js

(function (factory) {
    if ( typeof define === 'function' && define.amd ) {
        // AMD. Register as an anonymous module.
        define(['jquery'], factory);
    } else if (typeof exports === 'object') {
        // Node/CommonJS style for Browserify
        module.exports = factory;
    } else {
        // Browser globals
        factory(jQuery);
    }
}(function ($) {
一个区别是,它为Node/CommonJS导出返回一个构造函数,这样您就可以传入希望扩展的jQuery对象


另一方面,您的UMD实现有一个问题,在AMD部分

你有:

factory(require(['b'])); // AMD
如果您需要:

define(['b'], factory); // AMD
由于AMD是异步的,您将无法同步地需要角度模块

(function (root, factory) {
  if (typeof define === 'function' && define.amd) {
    define(['b'], factory); // AMD
  } else if (typeof exports === 'object') {
    factory(require('b')); // Node
  } else {
    factory(root.b); // browser global (root is window)
  }
}(this, function (b) {
  // use b in some fashion
}));

我认为通常由构建工具来决定要包含哪个版本的库(调试还是压缩)。另外,如果他是在开发angular库,那么假设并要求angular而不是其他人的库是非常合理的。只要我的两分钱。我不是在说“缩小还是不缩小”,想想jquery和zepto:完全不同的库,但99%的API是相同的,所以几乎任何依赖jquery的插件都可以与zepto配合使用。。。只要它不盲目加载自己的jquery。我可以有一个与angular具有相同API的库,在这种情况下,模块“有益地”加载angular对我来说将是有用的相反。在这种情况下,我认为正确的实现将是一个接口,第三方库将实现该接口以提供一致的API。但这一切都是毫无意义的,因为@Bungle表示他想编写一个有角度的JS模块。因此,他不应该支持另一个图书馆,如果他不想-特别是因为角度是他的模块正在建立的基础,可以说是角Web应用的基础。但是,如果我们谈论的是日期,我会100%同意你的看法。jquery.mouseweel.js就是一个很好的例子,看起来非常有效,谢谢。@alexanderomara您应该将代码片段更改为正确的内容,而不是将其复制到OP的原始版本中,这样粗心的读者就不会只是将代码片段复制粘贴到您的文档中post@I-林果接球不错!复制粘贴失败。