Es gibt "futuristisches" JavaScript, das wir schreiben können. "Stage 0" bezieht sich auf Ideen für die JavaScript-Sprache, die noch Vorschläge sind. Dennoch könnte jemand diese Idee in ein Babel-Plugin umwandeln und es könnte in Code kompiliert werden, der an jeden Browser ausgeliefert werden kann. Für einige dieser glücklichen Vorschläge wird Stage 0 zu 1, 2, 3 und schließlich zu einem offiziellen Teil der Sprache.
Es gab eine Zeit, in der selbst die grundlegenden Funktionen von ES6 eher experimentell waren. Man würde keine Pfeilfunktion in die Produktion ausliefern – man würde sie zu ES5 kompilieren und diese stattdessen ausliefern. Aber ES6 (aka ES2015, vor vier Jahren!) ist nicht mehr experimentell. Seine Funktionen sind keine Vorschläge, Entwürfe oder Kandidaten. Sie sind fertige Teile der Sprache mit breiter Unterstützung.
Die größten Hürden bei der Browserunterstützung sind IE <= 11 und Safari <= 9. Es ist durchaus möglich, dass Sie diese Browser nicht unterstützen. In diesem Fall können Sie ES6-Funktionen frei in die Produktion ausliefern, und das sollten Sie wahrscheinlich auch tun, da Ihr Code kleiner und effizienter sein wird, als wenn Sie ihn zu ES5 kompilieren würden. Philip hat einige Tests durchgeführt und seine Ergebnisse deuten darauf hin, dass sowohl Dateigrößen als auch Parse-/Eval-Zeiten halbiert oder besser sein können, indem die neuen Funktionen übernommen werden. Wenn Sie jedoch Browser unterstützen müssen, die keine Unterstützung bieten, müssen Sie zu ES5 kompilieren, aber das bedeutet nicht, dass Sie ES5 an alle Browser ausliefern müssen. Darum geht es bei "Differential Serving".
Wie setzt man das um? Ein Weg, der verlockend clever ist, ist dieses Muster, das ich zuerst von Philip Walton schreiben sah
<!-- Browsers with ES module support load this file. -->
<script type="module" src="main.mjs"></script>
<!-- Older browsers load this file (and module-supporting -->
<!-- browsers know *not* to load this file). -->
<script nomodule src="main.es5.js"></script>
Lassen Sie sich von diesem .mjs-Zeug nicht verwirren; es ist nur eine erfundene Dateierweiterung, die bedeutet: "Dies ist eine JavaScript-Datei, die das importieren von ES6-Modulen unterstützt" und sie ist völlig optional. Ich würde sie wahrscheinlich nicht einmal verwenden.
Das Konzept ist aber großartig. Wir müssen keine ausgefallenen JavaScript-Feature-Tests schreiben und dann selbst eine Netzwerkanfrage für das richtige Bundle auslösen. Wir können diese Aufteilung direkt auf HTML-Ebene vornehmen. Ich habe sogar kleine Bibliotheken gesehen, die dies nutzen, um sich selbst zu beschränken, speziell auf moderne Browser.
John Stewart hat dies kürzlich getestet, um zu sehen, ob es die Aufgabe erfüllt, die wir ihm zuschreiben, und, falls ja, ob es sie gut erfüllt. Zuerst beschreibt er, wie man die beiden Bundles tatsächlich erstellt, was einige Webpack-Konfigurationen erfordert. Dann testete er, ob es tatsächlich funktionierte.
Die gute Nachricht ist, dass die meisten Browser – insbesondere neuere – mit Differential Serving perfekt zurechtkommen. Aber es gibt einige, die das nicht tun. Safari 10 (2016) ist ein besonders schlechter Übeltäter, da es beide Versionen herunterlädt und ausführt. Firefox 59 (2018) und IE 11 laden beide herunter (führen aber die richtige aus), und Edge 18 lädt irgendwie beide Versionen herunter und dann die Module-Version *nochmal*. Alles Browser, die ziemlich schnell verschwinden, aber nicht zu ignorieren sind. Es lohnt sich trotzdem? Wahrscheinlich. Ich wäre daran interessiert, alternative Techniken zu untersuchen, die gegen diese Fallstricke vorgehen.
Ich liefere das korrekte Paket basierend auf dem User Agent aus
Die Alternative, die keine Fallstricke aufweist, wurde hier beschrieben
https://medium.com/@WebReflection/a-universal-bundle-loader-6d7f3e628f93
Die TL;DR-Version lautet:
type=module(und bitte denken wir immer daran, dass .mjs nicht benötigt wird) wird direkt vor verzögerten Skripten geladenBeispiel
Das ubl.js (Universal Bundle Loader) wird wenige Zeilen enthalten
Das war's
Dadurch funktioniert jeder Browser bestmöglich, vom ältesten bis zum neuesten.
Der gebündelte Code sollte auf ES 2017, 2015 und 5 für beste Ergebnisse abzielen, aber es könnte auch einfach 2015 für
type=moduleund 5 fürnomodulesein.Ich bin kürzlich auf https://github.com/Polymer/prpl-server/blob/master/README.md#differential-serving gestoßen, das verschiedene Versionen Ihrer Anwendung für verschiedene Browser ausliefern kann, indem es Browserfunktionen anhand des User-Agent-Headers erkennt. Sie können es testen, indem Sie dem Polymer Starter Kit Beispiel folgen https://github.com/Polymer/polymer-starter-kit.
Es gibt eine JavaScript-Lösung, die Safari 10.1 hilft. https://gist.github.com/samthor/64b114e4a4f539915a95b91ffd340acc
Safari 10.1 ist nicht der Einzige. Hier eine robuste Lösung, die auf Feature-Erkennung statt UA-Sniffing basiert.
Vue-cli bietet das out-of-the-box an.
aus den Vue-cli Dokumenten