Für meine Schüler im ersten Jahr habe ich eine einfache ES5-basierte Bibliothek bereitgestellt, die mit dem Revealing Module Pattern geschrieben wurde. Hier ist ein Ausschnitt aus dem "Haupt" -Modul / Namespace, der andere Erweiterungen enthalten wird:
window.Library = (function ($) {
if (!$) {
alert("The Library is dependent on jQuery, which is not loaded!");
}
return {};
})(window.jQuery);
Dies funktioniert für fast 99,9% der Studenten, die neu in der Webentwicklung sind und keine ausgefallenen Dinge wie ES6 in Kombination mit Webpack oder Babel verwenden.
Die 0,1% haben mich nun gebeten, eine ES6-basierte Version bereitzustellen, die ordnungsgemäß importiert werden kann. Ich würde das gerne zur Verfügung stellen, aber ich bin mir nicht sicher, wie ich das am besten angehen soll.
Ich möchte natürlich den ES5-Weg beibehalten, damit meine Schüler die Datei einfach mit einem Skript-Tag einfügen und eingeben können, Library.SomeExtension.aFunction();
wo immer sie möchten. Darüber hinaus sind einige der Erweiterungen auf jQuery angewiesen, das auf ähnliche Weise wie das obige Snippet injiziert wird.
Ich suche jetzt nach einem wartbaren Weg, um das Beste aus beiden Welten mit einer Codebasis und jQuery als Abhängigkeit herauszuholen. Ich möchte 99,9% a geben window.Library
, während ich 0,1% eine Verwendungsmöglichkeit geben möchte import Library from 'library'
.
Kann ich dies mit einer einzelnen JS-Datei erreichen, die beides kann? Oder würde ich eine spezielle ES6-Version benötigen (kein Problem)? Und vor allem: Wie würde ich meinen Code (alle ähnlich dem obigen Snippet) so neu mischen, dass ich beide Situationen unterstützen kann?
Alle Hinweise werden sehr geschätzt!
EDIT: Nur als Randnotiz, ich habe bereits eine vorhanden gulpfile.js
, die diese Bibliothek durchläuft Babel
, minifiers
und andere Dinge. Das zu erweitern, um das oben genannte Problem zu lösen, ist also kein Problem!
quelle
Library.SubLibrary.functionName
Setup wirklich und auch in separaten Dateien behalten , selbst wenn jemand es als ES6 oder was auch immer importiert. (Dies liegt hauptsächlich daran, dass Erweiterungen sich auch gegenseitig verwenden können. Bei Verwendung eines Standard-ES6-Setups würde dies zu Zirkelverweisen führen.)export
haben und die andere zuweisenwindow
. Ich dachte, es wäre großartig, wenn beide in einer einzigen Datei ausgeführt werden könnten, da sich das so viel eleganter anfühlt, aber dasexport
Schlüsselwort scheint nur in a zu funktionierentype=module
. Ich weiß nicht, ob es eine Problemumgehung gibt oder ob es einfach unmöglich ist.Antworten:
Nachdem ich ein paar Nächte lang Code verschoben und so viele Gulp-Pakete installiert hatte, dass ich mich nicht mehr an alle erinnere, die ich ausprobiert habe, entschied ich mich schließlich für etwas, mit dem ich halb zufrieden bin.
Um zunächst meine eigene Frage zu beantworten, die auch von @Bergi in den Kommentaren unterstützt wurde:
Was habe ich am Ende getan? Lassen Sie mich ganz klar sagen, dass ich das IIFE-Modul-Setup, das ich (vorerst) in der ES5-Ausgabedatei hatte, unbedingt beibehalten wollte. Ich habe meine Codebasis auf reines ES6 aktualisiert und alle Arten von Kombinationen von Plugins ausprobiert (einschließlich Rollup.js, die von @David Bradshaw erwähnt wurden). Aber ich konnte sie einfach nicht zum Laufen bringen, oder sie würden die Ausgabe vollständig so beschädigen, dass die Browser das Modul nicht mehr laden oder die Sourcemap-Unterstützung einstellen könnten. Mit dem Projekt, das die Studenten gerade zu Ende gehen, habe ich bereits genug meiner Freizeit für die 0,1% meiner Studenten verschwendet. Also viel Glück im nächsten Jahr für eine "schönere" Lösung.
Ich habe mein UMD-Muster (wie von @Sly_cardinal erwähnt) auf jQuery basiert und diesen Code in a geworfen
Library.umd.js
. Für den ES6-Teil habe ich einLibrary.es6.js
mit nur einemexport default Library
drin gemacht.In beiden Dateien habe ich einen mehrzeiligen Kommentar
/*[Library.js]*/
eingefügt, in den ich die verkettete, nicht minimierte Library.js einfügen wollte.Ich habe meine vorhandene Gulp-Aufgabe geändert, um sie nur
Library.js
mitconcat
und zu erstellen,Babel
und sie an einem temporären Speicherort gespeichert. Ich habe mich dafür entschieden, die Unterstützung der Quellzuordnung in diesem Prozess zu opfern, da der verkettete Code in der Ausgabe perfekt lesbar war. Technisch gesehen hat die Unterstützung von Quellkarten "funktioniert", aber sie würde den Debugger immer noch zu sehr abwerfen.Ich habe eine zusätzliche Gulp-Aufgabe hinzugefügt, um den Inhalt der temporären
Library.js
Datei zu lesen. Dann habe ich für jede der Dateien aus Schritt 1 den mehrzeiligen Kommentar gefunden und durch den Inhalt ersetzt. Speichern Sie die resultierenden Dateien und werfen Sie sie dann durch das Finaleconcat
(z. B. Bundle mit jQuery)terser
und die Generierung der Quellkarte.Das Endergebnis sind zwei Dateien:
Obwohl ich mit dem Ergebnis zufrieden bin, mag ich die Gulp-Task-Kette und den Verlust der Sourcemap-Unterstützung in der ersten Hälfte des Prozesses nicht. Wie bereits erwähnt, habe ich zahlreiche Schluck-Plugins ausprobiert, um den gleichen Effekt zu erzielen (z. B.
gulp-inject
), aber sie haben entweder nicht richtig funktioniert oder seltsame Dinge an der Quellenkarte vorgenommen (selbst wenn sie behaupteten, sie zu unterstützen).Für ein nächstes Unterfangen könnte ich etwas anderes als Gulp untersuchen oder mein eigenes Plugin erstellen, das die oben genannten Schritte ausführt, aber richtig: P.
quelle
Mit Rollup.js können Sie Ihren Code als ES5-Bibliothek sowie als zugehöriges ES6-Modul bündeln.
Rollup verfügt über eine integrierte Unterstützung für Gulp, sodass so etwas ein vernünftiger Ausgangspunkt wäre (basierend auf dem Gulp-Beispiel von Rollup):
Weitere Informationen zu den verschiedenen verfügbaren Ausgabeformaten finden Sie unter: https://rollupjs.org/guide/en/#outputformat
Im Allgemeinen ist es am einfachsten, wenn Ihre Bibliotheksquelle mit ES-Modulen geschrieben und dann in das ES5-Bundle gebündelt / transpiliert wird.
quelle