Der folgende Beitrag stammt von Pascal Klau, einem Auszubildenden aus Süddeutschland, der unnötige HTTP-Anfragen und Brokkoli nicht mag. Pascal wird einen Weg erklären, wie man einen Polyfilling-Service so nutzt, dass man ihn möglicherweise gar nicht mehr verwenden muss.
Die Situation
Wir möchten JavaScript in ES6-Syntax schreiben. Da wir aber ältere Browser unterstützen müssen, die ES6 nicht verstehen, müssen wir uns damit auseinandersetzen.
Hier ist das Standardverfahren: ES6 schreiben → alles nach ES5 kompilieren (z.B. Babel) → das an den Browser senden.
Das ist vielleicht nicht mehr der effizienteste Weg. Das Problem ist, dass wir moderne Browser zwingen, den alten Code auszuführen, wenn sie es nicht müssten. Sie unterstützen ES6, also können wir ihnen nicht auch ES6 geben.
Ein besserer Weg
Es gibt ein Polyfill-Projekt namens Polyfill.io API, das ES6-Code clientseitig polyfillen kann.

Es implementiert auch Polyfills für einige HTML-Features wie das <picture>-Element.
Beschreibung von ihrer Website
Polyfill.io liest den User-Agent (UA) Header jeder Anfrage und liefert Polyfills, die für den anfragenden Browser geeignet sind. Passen Sie die Antwort basierend auf den Features an, die Sie in Ihrer App verwenden [...].
Es wird von Financial Times entwickelt, daher hat es eine gewisse Unterstützung und wir können ziemlich sicher sein, dass es nicht verschwinden wird.
Eins ist klar: Polyfill.io bietet keine Unterstützung für syntaktischen Zucker. Zum Beispiel Klassen, erweiterte Objektliterale und Dinge wie Pfeilfunktionen. Dafür bräuchte man immer noch einen Compiler.
Polyfill.io einrichten
Polyfill.io zu Ihrem Projekt hinzuzufügen, kann so einfach sein. Fügen Sie das CDN-gehostete Skript zu Ihrer Seite hinzu.
<script src="https://cdn.polyfill.io/v2/polyfill.min.js"></script>
Beim Ausführen des Skripts werden der UA und die gewünschten Features ausgegeben.
UA detected: chrome/56.0.0
Features requested: default
Request-Parameter ändern
Es gibt eine Reihe von Optionen zur Anpassung der Anfrage, die Sie in die Skriptquelle einfügen.
Funktionen
Liste der zu polyfillenden Browser-Features. Akzeptiert eine durch Kommas getrennte Liste von Feature-Namen. Verfügbare Feature-Namen finden Sie auf der Seite Browser und Features.
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=fetch"></script>
In Safari 10 sagt das Skript jetzt so etwas
Features requested: fetch
- setImmediate, License: CC0 (required by "Promise", "fetch")
- fetch
Wenn ein Feature wie fetch von einem anderen Feature wie Promise abhängt, fügt Polyfill.io es automatisch hinzu.
Flags
- always – Polyfill soll unabhängig davon einbezogen werden, ob es vom anfragenden User-Agent benötigt wird.
- gated – Wenn der Polyfill in das Bundle aufgenommen wird, wird er von einer Feature-Erkennung begleitet, die den Polyfill nur dann ausführt, wenn die native API nicht vorhanden ist.
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=fetch&flags=gated"></script>
Callback
Name einer Funktion, die nach dem Laden der Polyfills aufgerufen wird. Dies ist einfach eine Möglichkeit, Ihren eigenen Code auszulösen, sobald die Polyfills geladen sind. Er soll es ermöglichen, dass der Polyfill-Service einfacher asynchron mit `async` und `defer` Attributen geladen werden kann.
Das Problem
So gut all das auch klingt, es ist immer noch nicht perfekt.
Moderne Browser müssen jetzt kein ES5 mehr laden, sondern müssen stattdessen einen Server-Roundtrip (eine HTTP-Anfrage) machen, um zu prüfen, ob Polyfills benötigt werden.
Das hat mich so sehr gestört, dass ich an einem kleinen Projekt gearbeitet habe, um zu helfen.
Ein noch besserer Weg
Dynamischen Polyfill einrichten
Das von mir erstellte npm-Paket heißt dynamic-polyfill. Es prüft, ob das Feature nativ unterstützt wird oder nicht, bevor eine Serveranfrage gestellt wird.
Die Einrichtung sieht so aus
import polyfill from 'dynamic-polyfill'
polyfill({
fills: 'fetch, Promise',
options: 'gated', // default: null
minify: false, // default: true
afterFill() {
main()
}
})
function main() {
// app code here
}
Das wird im Wesentlichen so ausgeführt, in Klartext
Gibt es [window.fetch, window.Promise]?
Wenn ja, rufe den afterFill() Callback auf.
Wenn nein, erstelle ein <script> Tag mit dem `async`-Attribut, füge den Polyfill.io-Link mit allen bereitgestellten Optionen ein und rufe den afterFill() Callback auf, nachdem er geladen wurde.
Hinweis: Nicht alle Optionen werden bisher unterstützt, nur die wichtigsten.
Geringer Fußabdruck
Da dieses Modul weniger als 1 KB minifiziert ist und keine Abhängigkeiten hat, hat es einen super kleinen Fußabdruck in Ihrem Projekt.
Fazit
Schreiben Sie zukunftssicheres und effizientes JavaScript für moderne Browser. Lassen Sie Polyfill.io ältere Browser handhaben. Machen Sie keine zusätzliche HTTP-Anfrage, wenn es nicht sein muss.
Stellen Sie nur sicher, dass Sie etwas zur Hand haben, um diese Freudentränen zu trocknen.
Dieser Artikel erscheint etwas seltsam. Er spricht davon, "ES6-Syntax" zu schreiben, und dann von "Polyfilling von Features". Kein noch so gezieltes Polyfilling wird Ihnen Pfeilfunktionen, const, let oder andere Syntax in älteren Browsern verschaffen.
Ich bin ebenfalls äußerst verwirrt. Was machen wir also mit der ES2015+-Syntax? Kompilieren wir das immer noch, aber irgendwie ohne ES2015+-Bibliotheken? Aber wie funktioniert das dann mit Modul-Ladern? :X
Was vielleicht *wirklich cool* wäre, ist eine Möglichkeit, ES2015-Code direkt in unterstützenden Browsern (Syntax und alles) zu laden und gleichzeitig ES5 für nicht unterstützende (oder teilweise unterstützende) Browser bereitzustellen. Immer noch unsicher, wie Modul-Lader funktionieren würden. Und es würde den Debugging-Aufwand verdoppeln, da es zwei verschiedene Ausführungspfade gäbe, je nach Unterstützung oder deren Fehlen.
Ich glaube, hier gibt es eine Verwechslung zwischen ES6-Syntax, die nicht polyfillt werden kann und in älteren Browsern Fehler verursacht, und neuen JS-APIs, die polyfillt werden können.
Wenn Sie ältere Browser unterstützen wollen, können Sie das Transpilieren von ES6 nach ES5 nicht überspringen.
Das scheint mir völlig nutzlos zu sein. Sie verschwenden also eine zusätzliche HTTP-Anfrage, um eine Drittanbieter-API nach Polyfills für `Array.values` oder `String.contains` zu fragen, aber Sie müssen immer noch in ES5 codieren, d.h. ohne Pfeilfunktionen, Standardparameter, Destrukturierung usw. usw. Mit dem Risiko, dass Sie am Arsch sind, wenn deren Seite ausfällt oder einfach langsam ist.
Entschuldigung, aber ich sehe wirklich nicht den Sinn.
Ja, das klingt, als würde es die Fragmentierung von ES-Versionen nur weiter erhöhen. Sie werden ES6, transpilierte ES6, ES6 (aber nicht mit Klassen, =>, etc.), ES5, Modernizr haben...
Warum machen wir nicht einfach Feature-Erkennung und lösen dynamisch das differenzierte Laden einer transpilieren oder ES6-Bibliothek aus? Das könnte ein Polyfill im Stamm-Dokument sein (wenn wir eine SPA machen, sonst wird das komplizierter), damit wir keine kostbaren Anfragen verschwenden müssen.
Etwas in der Art von (sehr grob und schnell)
Ich denke immer noch, dass das Herunterladen von ein paar KB an Babel-Polyfills in den meisten praktischen Fällen völlig akzeptabel ist, solange ES6-Imports noch nicht nativ unterstützt werden.
Nach Überprüfung des Codes in der Bibliothek funktioniert er nicht einmal richtig... Er hat nicht einmal Tests im Repository.
Dieser Beitrag hätte von Chris oder jemand anderem vom CSS-Tricks-Team überprüft und code-getestet werden sollen, damit er korrekt funktioniert.
Falls Sie in Zukunft irgendwelche Probleme haben
"Es funktioniert nicht!" hilft niemandem wirklich. :)
Bei mir scheint es einwandfrei zu funktionieren. Welches Problem haben Sie?
Danke http://www.altunyusufelihaliyikama.com
Hallo Pascal Klau,
Vielen Dank für das Teilen. Die Dokumentation sieht sehr hilfreich und attraktiv aus und wir würden sie auch gerne in unseren Projekten verwenden. Aber ich habe festgestellt, dass in den Referenzdateien nichts geschrieben steht. Alle diese Dateien sind leer. https://polyfill.io/v2/polyfill.min.js oder https://polyfill.io/v2/polyfill.js. Ist das eine Dummy-URL?
Wenn ich https://polyfill.io/v2/polyfill.min.js aufrufe, erhalte ich folgende Meldung:
Und wenn ich das `min` wie in der Anleitung beschrieben aus der URL entferne, erhalte ich folgende Meldung:
Könnten Sie bitte weitere Details mitteilen, falls es kürzlich Änderungen an der URL gab?
Vielen Dank im Voraus :)
Ich denke, das ist irgendwie der Punkt. Es wurde erkannt, dass Sie sich in Chrome 55 befinden und keine Polyfills benötigen. (Aber Sie mussten trotzdem die HTTP-Anfrage machen, um das herauszufinden.)