2015-01-18 6 views
5

Ich erstelle mein erstes AngularJS-Modul für die Open-Source-Distribution. Ich möchte es so verpacken, dass es für andere leicht zu konsumieren ist.Ist es sinnvoll, UMD ohne Exporte zu verwenden, um einfach eine Abhängigkeit zu erhöhen?

Das UMD-Projekt bietet ein pattern für den Export von JavaScript-Module, die mit AMD kompatibel sind, Commonjs (oder zumindest Node) und Browser-Globals:

(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 
})); 

Da jedoch AngularJS sein eigenes internes Modulsystem, Registrierung Ein Modul wird ausgeführt, indem einfach eine Methode auf dem Objekt angular aufgerufen wird, dh angular.module(). Daher müsste ein UMD-Modul nichts exportieren. es müsste nur angular anfordern und handeln. In Bezug auf das vorherige Beispiel, denke ich, dass so etwas wie dies aussehen:

(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 
})); 

Oder spezifisch meinem Fall:

(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(...); 
})); 

Ist das keine große Sache, oder geht es gegen den Geist von UMD? Ich frage, weil ich keine UMD-Muster finden konnte, die nichts exportieren.

Antwort

1

Als eckiges Plugin könnte es netter sein, stattdessen ein Modul anzubieten, das den Builder exportiert, so dass die Leute verantwortlich bleiben für "welche eckigen Mittel". Zum Beispiel, sagen wir, ich benutze eine angepasste Debug-Version von eckig, aber möchte Ihren Code verwenden: im Moment kann ich nicht, weil Sie beschlossen haben, angular in für mich zu verlangen. Das scheint wie eine gute Idee, aber wirklich nicht ist:

var myangular = require('debug-angular/ext/symbolised'); 
var yourmodule = require('yourmodule'); 
yourmodule.register(myangular); 

Jetzt weiß ich, wie Entwickler, dass Ihr Code mein Winkel verwenden wird, anstatt jetzt zwei verschiedene Versionen von Winkeln geladen zu haben, mit all die komischen Versionen, die nicht zusammenpassen, Bugs, die daraus entstehen.

So eine viel schönere umd Fabrik wäre dies:

(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(...); 
})); 
+1

Ich würde argumentieren, dass es in der Regel an dem Build-Tool liegt zu entscheiden, welche Version der Bibliothek enthalten (Debug vs. komprimiert). Auch, wenn er die Bibliothek gegen Winkel entwickelt, ist es durchaus vernünftig anzunehmen und zu erfordern, und zwar nicht von jemand anderem. Nur meine zwei Cent. – icfantv

+0

Ich spreche nicht nur über "minimized oder nicht", denken Sie an jquery vs. zepto: komplett verschiedene Bibliotheken, aber 99% gleiche API, so dass praktisch jedes Plugin, das auf jQuery beruht, gut mit zepto ... funktioniert es blendet nicht seine eigene jQuery. Ich könnte eine Bibliothek mit der gleichen API wie eckig haben, in welchem ​​Fall das Modul "hilfreich" Laden Winkel für mich wird das Gegenteil von sinnvoll sein. –

+0

In diesem Fall würde ich argumentieren, dass die richtige Implementierung eine Schnittstelle wäre, die die Drittanbieterbibliothek implementieren würde, um eine konsistente API bereitzustellen. Aber das ist alles egal, da @Bungle angedeutet hat, dass er ein angulares JS-Modul schreiben möchte. Er sollte also keine andere Bibliothek unterstützen müssen, wenn er nicht will - zumal angular das Fundament für sein Modul ist und wohl die Grundlage für eckige Webanwendungen ist. Wenn wir über Daten sprechen würden, würde ich Ihnen jedoch 100% zustimmen. – icfantv

1

ich bei der Verwendung dieses Musters nicht alles falsch sehen. Wie Sie wahrscheinlich festgestellt haben, spielt Angular nicht sehr gut mit vorhandenen Modulsystemen zusammen, da es ein eigenes verwendet, aber ein Modul muss nichts exportieren. Wie oft exportiert das Hauptmodul für ein Projekt irgendetwas? Normalerweise bekommt es nur Abhängigkeiten.

Wenn Sie nach einem Beispiel suchen, das etwas Ähnliches macht, können Sie das jQuery Mousewheel-Plugin betrachten, das UMD verwendet, aber von jQuery abhängig ist.

Auszug aus 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 ($) { 

Der einzige Unterschied ist, dass es einen Konstruktor für den Node/Commonjs Export zurückkehren, so dass Sie in der jQuery-Objekt übergeben können Sie erweitern möchten .


Nebenbei bemerkt gibt es ein Problem mit Ihrer UMD-Implementierung, in der AMD-Abschnitt.

Sie haben:

factory(require(['b'])); // AMD 

Wo würden Sie brauchen:

define(['b'], factory); // AMD 

Da AMD asynchron ist, würden Sie nicht synchron Lage sein, die Winkelmodul benötigen.

+0

jquery.mousewheel.js ist ein sehr gutes Beispiel dafür, sieht gut aus, danke. – estus

+0

@alexanderomara Sie sollten das Snippet zu dem, was korrekt ist, anstatt einer Kopie des Originals des OPs ändern, damit unvorsichtige Leser das Snippet nicht einfach in Ihren Beitrag kopieren und einfügen –

+0

@ I-LinKuo Guter Fang! Kopieren-Einfügen fehlgeschlagen. –

Verwandte Themen