Hier ist ein konkreteres Beispiel.
Ich arbeite in einem Projekt mit 60 Dateien. Wir haben 2 verschiedene Modi, um es auszuführen.
Laden Sie eine verkettete Version, 1 große Datei. (Produktion)
Laden Sie alle 60 Dateien (Entwicklung)
Wir verwenden einen Loader, sodass wir nur ein Skript auf der Webseite haben
<script src="loader.js"></script>
Der Standardwert ist Modus 1 (Laden der einen großen verketteten Datei). Um den In-Modus Nr. 2 (separate Dateien) auszuführen, setzen wir ein Flag. Es könnte alles sein. Ein Schlüssel in der Abfragezeichenfolge. In diesem Beispiel machen wir das einfach
<script>useDebugVersion = true;</script>
<script src="loader.js"></script>
loader.js sieht ungefähr so aus
if (useDebugVersion) {
injectScript("app.js");
injectScript("somelib.js");
injectScript("someotherlib.js");
injectScript("anotherlib.js");
... repeat for 60 files ...
} else {
injectScript("large-concatinated.js");
}
Das Build-Skript ist nur eine .sh-Datei, die so aussieht
cat > large-concantinated.js app.js somelib.js someotherlib.js anotherlib.js
etc...
Wenn eine neue Datei hinzugefügt wird, verwenden wir wahrscheinlich Modus 2, da wir die Entwicklung durchführen, müssen wir eine hinzufügen injectScript("somenewfile.js")
loader.js Zeile hinzufügen
Später für die Produktion müssen wir dann auch somenewfile.js zu unserem Build-Skript hinzufügen. Ein Schritt, den wir oft vergessen und dann Fehlermeldungen erhalten.
Durch den Wechsel zu AMD müssen nicht 2 Dateien bearbeitet werden. Das Problem, loader.js und das Build-Skript synchron zu halten, verschwindet. Verwenden von r.js
oderwebpack
es kann nur den zu erstellenden Code lesenlarge-concantinated.js
Es kann auch mit Abhängigkeiten umgehen, zum Beispiel hatten wir 2 Dateien lib1.js und lib2.js so geladen
injectScript("lib1.js");
injectScript("lib2.js");
lib2 braucht lib1. Es enthält Code, der so etwas wie tut
lib1Api.installPlugin(...);
Da die injizierten Skripte jedoch asynchron geladen werden, gibt es keine Garantie dafür, dass sie in der richtigen Reihenfolge geladen werden. Diese beiden Skripte sind keine AMD-Skripte, aber mit require.js können wir ihre Abhängigkeiten erkennen
require.config({
paths: {
lib1: './path/to/lib1',
lib2: './path/to/lib2',
},
shim: {
lib1: {
"exports": 'lib1Api',
},
lib2: {
"deps": ["lib1"],
},
}
});
In unserem Modul, das lib1 verwendet, machen wir das
define(['lib1'], function(lib1Api) {
lib1Api.doSomething(...);
});
Jetzt wird require.js die Skripte für uns injizieren und lib2 erst injizieren, wenn lib1 geladen wurde, da wir gesagt haben, dass lib2 von lib1 abhängt. Es wird auch unser Modul, das lib1 verwendet, erst gestartet, wenn sowohl lib2 als auch lib1 geladen wurden.
Dies macht die Entwicklung angenehm (kein Build-Schritt, keine Sorge um die Ladereihenfolge) und die Produktion (keine Notwendigkeit, ein Build-Skript für jedes hinzugefügte Skript zu aktualisieren).
Als zusätzlichen Bonus können wir das Babel-Plugin von Webpack verwenden, um Babel über den Code für ältere Browser auszuführen, und auch dieses Build-Skript müssen wir nicht warten.
Beachten Sie, dass wenn Chrome (unser Browser der Wahl) anfangen würde, import
wirklich zu unterstützen, wir wahrscheinlich für die Entwicklung zu diesem wechseln würden, aber das würde nichts wirklich ändern. Wir könnten weiterhin Webpack verwenden, um eine verkettete Datei zu erstellen, und wir könnten es verwenden, um Babel über den Code für alle Browser auszuführen.
All dies wird dadurch erreicht, dass keine Skript-Tags und AMD verwendet werden