RequireJS scheint intern etwas zu tun, das die erforderlichen Javascript-Dateien zwischenspeichert. Wenn ich eine Änderung an einer der erforderlichen Dateien vornehme, muss ich die Datei umbenennen, damit die Änderungen übernommen werden.
Der übliche Trick, eine Versionsnummer als Querystring-Parameter an das Ende des Dateinamens anzuhängen, funktioniert bei requirejs nicht <script src="jsfile.js?v2"></script>
Was ich suche, ist eine Möglichkeit, dieses interne Cacheing von RequireJS-erforderlichen Skripten zu verhindern, ohne meine Skriptdateien bei jeder Aktualisierung umbenennen zu müssen.
Plattformübergreifende Lösung:
Ich verwende es jetzt urlArgs: "bust=" + (new Date()).getTime()
für das automatische Cache-Busting während der Entwicklung und urlArgs: "bust=v2"
für die Produktion, bei der ich die fest codierte Versionsnummer nach dem Rollout eines aktualisierten erforderlichen Skripts erhöhe.
Hinweis:
@Dustin Getz erwähnte kürzlich in einer Antwort, dass Chrome Developer Tools beim Debuggen Haltepunkte löschen, wenn Javascript-Dateien auf diese Weise kontinuierlich aktualisiert werden. Eine Problemumgehung besteht darin, debugger;
Code zu schreiben , um in den meisten Javascript-Debuggern einen Haltepunkt auszulösen.
Serverspezifische Lösungen:
In den folgenden Antworten finden Sie spezifische Lösungen, die für Ihre Serverumgebung möglicherweise besser funktionieren, z. B. Node oder Apache.
quelle
Antworten:
RequireJS kann so konfiguriert werden, dass an jede der Skript-URLs ein Wert für das Cache-Busting angehängt wird.
Aus der RequireJS-Dokumentation ( http://requirejs.org/docs/api.html#config ):
Beispiel: Anhängen von "v2" an alle Skripte:
Zu Entwicklungszwecken können Sie RequireJS zwingen, den Cache zu umgehen, indem Sie einen Zeitstempel anhängen:
quelle
urlArgs: "bust=" + (new Date()).getTime()
für das automatische Cache-Busting während der Entwicklung undurlArgs: "bust=v2"
für die Produktion, bei der ich die fest codierte Versionsnummer nach dem Rollout eines aktualisierten erforderlichen Skripts erhöhe.urlArgs: "bust=" + (+new Date)
urlArgs
.Verwenden Sie hierfür keine urlArgs!
Das Laden von Skripten berücksichtigt die HTTP-Caching-Header. (Skripte werden mit einem dynamisch eingefügten Skript geladen
<script>
, was bedeutet, dass die Anforderung genauso aussieht wie jedes alte Asset, das geladen wird.)Stellen Sie Ihre Javascript-Assets mit den richtigen HTTP-Headern bereit, um das Caching während der Entwicklung zu deaktivieren.
Wenn Sie die urlArgs von require verwenden, bleiben die von Ihnen festgelegten Haltepunkte bei Aktualisierungen nicht erhalten. Am Ende müssen Sie
debugger
Anweisungen überall in Ihren Code einfügen. Schlecht. Ich verwende esurlArgs
für Cache-Busting-Assets während Produktions-Upgrades mit dem Git Sha. Dann kann ich festlegen, dass mein Vermögen für immer zwischengespeichert wird und garantiert niemals veraltetes Vermögen hat.In der Entwicklung verspotte ich alle Ajax-Anforderungen mit einer komplexen Mockjax- Konfiguration. Anschließend kann ich meine App im Nur-Javascript-Modus mit einem 10-Zeilen-Python-HTTP-Server mit deaktiviertem Caching bereitstellen . Dies hat sich für mich zu einer ziemlich großen "unternehmerischen" Anwendung mit Hunderten von erholsamen Webservice-Endpunkten ausgeweitet. Wir haben sogar einen Vertragsdesigner, der mit unserer realen Produktionscodebasis arbeiten kann, ohne ihm Zugriff auf unseren Backend-Code zu gewähren.
quelle
debugger;
Ihren Code überall dort verwenden, wo ein Haltepunkt bestehen bleiben soll.Die urlArgs-Lösung weist Probleme auf. Leider können Sie nicht alle Proxyserver steuern, die sich möglicherweise zwischen Ihnen und dem Webbrowser Ihres Benutzers befinden. Einige dieser Proxyserver können leider so konfiguriert werden, dass URL-Parameter beim Zwischenspeichern von Dateien ignoriert werden. In diesem Fall wird Ihrem Benutzer die falsche Version Ihrer JS-Datei zugestellt.
Ich gab schließlich auf und implementierte mein eigenes Update direkt in require.js. Wenn Sie bereit sind, Ihre Version der requirejs-Bibliothek zu ändern, funktioniert diese Lösung möglicherweise für Sie.
Sie können den Patch hier sehen:
https://github.com/jbcpollak/requirejs/commit/589ee0cdfe6f719cd761eee631ce68eee09a5a67
Nach dem Hinzufügen können Sie in Ihrer erforderlichen Konfiguration Folgendes tun:
Verwenden Sie Ihr Build-System oder Ihre Serverumgebung, um diese
buildNumber
durch eine Revisions-ID / Softwareversion / Lieblingsfarbe zu ersetzen .Verwendung erfordern wie folgt:
Wird erforderlich sein, um diese Datei anzufordern:
In unserer Serverumgebung verwenden wir Regeln zum Umschreiben von URLs, um die buildNumber zu entfernen und die richtige JS-Datei bereitzustellen. Auf diese Weise müssen wir uns nicht um das Umbenennen aller unserer JS-Dateien kümmern.
Der Patch ignoriert alle Skripte, die ein Protokoll angeben, und wirkt sich nicht auf Nicht-JS-Dateien aus.
Dies funktioniert gut für meine Umgebung, aber mir ist klar, dass einige Benutzer lieber ein Präfix als ein Suffix bevorzugen. Es sollte einfach sein, mein Commit an Ihre Bedürfnisse anzupassen.
Aktualisieren:
In der Pull-Request-Diskussion schlägt der Autor von requirejs vor, dass dies als Lösung für das Präfix der Revisionsnummer dienen könnte:
Ich habe dies nicht versucht, aber die Implikation ist, dass dies die folgende URL anfordern würde:
Was für viele Leute, die ein Präfix verwenden können, sehr gut funktionieren könnte.
Hier sind einige mögliche doppelte Fragen:
RequireJS und Proxy-Caching
require.js - Wie kann ich eine Version für erforderliche Module als Teil der URL festlegen?
quelle
/scripts/myLib/v1.1/
. Ich habe versucht, meinen Dateinamen ein Postfix (oder Präfix) hinzuzufügen, wahrscheinlich, weil dies bei jquery der Fall ist, aber nach einer Weile wurde ich faul und begann, eine Versionsnummer im übergeordneten Ordner zu erhöhen. Ich denke, es hat mir die Wartung auf einer großen Website erleichtert, aber jetzt mache ich mir Sorgen über Alpträume beim Umschreiben von URLs.<script data-main="${pageContext.request.contextPath}/resources/scripts/main" src="${pageContext.request.contextPath}/resources/scripts/require.js"> <jsp:text/> </script> <script> require([ 'dev/module' ]); </script>
Inspiriert vom Expire-Cache auf require.js data-main haben wir unser Bereitstellungsskript mit der folgenden Ant-Task aktualisiert:
Wo der Anfang von main.js aussieht:
quelle
In Produktion
urlArgs
kann Probleme verursachen!Der Hauptautor von requirejs zieht es vor,
urlArgs
Folgendes nicht zu verwenden :[Styling meins.]
Ich folge diesem Rat.
In Entwicklung
Ich bevorzuge die Verwendung eines Servers, der Dateien, die sich häufig ändern können, intelligent zwischenspeichert: einen Server, der bei Bedarf 304 ausgibt
Last-Modified
und darauf antwortetIf-Modified-Since
. Sogar ein Server, der auf dem Express- Set von Node basiert , um statische Dateien bereitzustellen, erledigt dies sofort. Es erfordert nichts mit meinem Browser zu tun und bringt keine Haltepunkte durcheinander.quelle
Ich habe dieses Snippet aus AskApache genommen und es in eine separate .conf-Datei meines lokalen Apache-Webservers (in meinem Fall /etc/apache2/others/preventcaching.conf) gestellt:
Für die Entwicklung funktioniert dies einwandfrei, ohne dass der Code geändert werden muss. Für die Produktion könnte ich den Ansatz von @ dvtoever verwenden.
quelle
Schnelle Lösung für die Entwicklung
Für die Entwicklung können Sie einfach den Cache in Chrome Dev Tools deaktivieren ( Deaktivieren des Chrome-Cache für die Website-Entwicklung ). Das Deaktivieren des Caches erfolgt nur, wenn das Dialogfeld "Entwicklertools" geöffnet ist. Sie müssen sich also nicht jedes Mal umschalten, wenn Sie diese Option durchsuchen.
Hinweis: Die Verwendung von ' urlArgs ' ist die richtige Lösung in der Produktion, damit Benutzer den neuesten Code erhalten. Das Debuggen wird jedoch schwierig, da Chrome bei jeder Aktualisierung Haltepunkte ungültig macht (da jedes Mal eine "neue" Datei bereitgestellt wird).
quelle
Ich empfehle nicht, ' urlArgs ' zu verwenden ' für Cache mit RequireJS zu verwenden. Da dies das Problem nicht vollständig löst. Wenn Sie eine Versionsnummer aktualisieren, werden alle Ressourcen heruntergeladen, obwohl Sie nur eine einzelne Ressource geändert haben.
Um dieses Problem zu beheben, empfehle ich die Verwendung von Grunt-Modulen wie 'filerev' zum Erstellen der Revisionsnummer. Darüber hinaus habe ich eine benutzerdefinierte Aufgabe in Gruntfile geschrieben, um die Revision zu aktualisieren, sofern dies nicht erforderlich ist.
Bei Bedarf kann ich das Code-Snippet für diese Aufgabe freigeben.
quelle
So mache ich es in Django / Flask (kann leicht an andere Sprachen / VCS-Systeme angepasst werden):
In Ihrem
config.py
(ich verwende dies in Python3, daher müssen Sie möglicherweise die Codierung in Python2 anpassen)Dann in Ihrer Vorlage:
git rev-parse HEAD
Wird beim Start der App nur einmal ausgeführt und imconfig
Objekt gespeichertquelle
Dynamische Lösung (ohne urlArgs)
Für dieses Problem gibt es eine einfache Lösung, sodass Sie für jedes Modul eine eindeutige Versionsnummer laden können.
Sie können die ursprüngliche Funktion requirejs.load speichern, sie mit Ihrer eigenen Funktion überschreiben und Ihre geänderte URL erneut auf die ursprüngliche Funktion requirejs.load analysieren:
In unserem Erstellungsprozess habe ich "gulp-rev" verwendet, um eine Manifestdatei mit allen Überarbeitungen aller verwendeten Module zu erstellen. Vereinfachte Version meiner Schluckaufgabe:
Dadurch wird ein AMD-Modul mit den Revisionsnummern für moduleNames generiert, das in der Datei main.js als 'oRevision' enthalten ist. Dort überschreiben Sie die Funktion requirejs.load wie zuvor gezeigt.
quelle
Dies ist zusätzlich zu der von @phil mccull akzeptierten Antwort.
Ich verwende seine Methode, automatisiere aber auch den Prozess, indem ich eine T4-Vorlage erstelle, die vor dem Build ausgeführt werden soll.
Pre-Build-Befehle:
T4-Vorlage:
Generierte Datei:
In Variable speichern, bevor require.config.js geladen wird:
Referenz in require.config.js:
quelle
In meinem Fall wollte ich bei jedem Klick dasselbe Formular laden. Ich wollte nicht, dass die Änderungen, die ich an der Datei vorgenommen habe, erhalten bleiben. Es ist möglicherweise nicht genau für diesen Beitrag relevant, aber dies könnte eine mögliche Lösung auf der Clientseite sein, ohne die Konfiguration für erforderlich festzulegen. Anstatt den Inhalt direkt zu senden, können Sie eine Kopie der erforderlichen Datei erstellen und die eigentliche Datei intakt halten.
quelle