Разумно ли использовать UMD без экспорта, чтобы просто увеличить зависимость?
Я создаю свой первый модуль AngularJS, предназначенный для распространения с открытым исходным кодом. Я бы хотел упаковать его так, чтобы его могли легко использовать другие.
Проект UMD предоставляет шаблон для экспорта модулей JavaScript, совместимых с AMD, CommonJS (или хотя бы Node) и глобальными переменными браузера:
(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, которые ничего не экспортируют.
2 ответа
Я не вижу ничего плохого в использовании этого шаблона. Как вы, вероятно, обнаружили, Angular не очень хорошо работает с существующими модульными системами, поскольку использует свою собственную, но модуль не должен ничего экспортировать. Как часто основной модуль проекта экспортирует что-либо? Обычно он просто получает зависимости.
Если вы ищете пример, который делает нечто подобное, вы можете посмотреть на плагин jQuery mousewheel, который использует UMD, но зависит от jQuery.
Выдержка из
jquery.mousewheel.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 in для меня. Это кажется отличной идеей, но на самом деле это не так:
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( ... );
}));