Frage

RequiredJs scheint etwas intern zu tun, dass Caches JavaScript -Dateien erfordert. Wenn ich eine der erforderlichen Dateien ändern muss, muss ich die Datei umbenennen, damit die Änderungen angewendet werden.

Der übliche Trick, eine Versionsnummer als QueryString -Param bis zum Ende des Dateinamens anzuhängen <script src="jsfile.js?v2"></script>

Was ich suche, ist eine Möglichkeit, dieses interne Cacheeing von forderJS -erforderlichen Skripten zu verhindern, ohne meine Skriptdateien jedes Mal umbenennen zu müssen, wenn sie aktualisiert werden.

Plattformübergreifende Lösung:

Ich benutze jetzt urlArgs: "bust=" + (new Date()).getTime() Für automatische Cache-Busting während der Entwicklung und urlArgs: "bust=v2" Für die Produktion, bei der ich die hartcodierte Version num erhöht, nachdem ich ein aktualisiertes Skript ausgelöst habe.

Notiz:

@Dustin Getz erwähnt in einer kürzlich erwähnten Antwort, dass Chrome -Entwickler -Tools beim Debuggen Bruchpunkte fallen lassen, wenn JavaScript -Dateien kontinuierlich so aktualisiert werden. Eine Problemumgehung ist zu schreiben debugger; in Code, um einen Haltepunkt in den meisten JavaScript -Debuggern auszulösen.

Serverspezifische Lösungen:

Für bestimmte Lösungen, die für Ihre Serverumgebung wie Knoten oder Apache besser funktionieren, finden Sie einige der folgenden Antworten.

War es hilfreich?

Lösung

RequiredJs kann so konfiguriert werden, dass sie jedem Skript -URLs für das Cache -Busting einen Wert angehängt haben.

Aus der Anforderungsdokumentation (http://requirejs.org/docs/api.html#config):

Urlargs: Zusätzliche Argumente für Abfragen Zeichenfolge, die an URLs angehängt sind, für die Js verwendet werden, um Ressourcen abzurufen. Am nützlichsten, um die Büste zu leiten, wenn der Browser oder Server nicht korrekt konfiguriert ist.

Beispiel: "v2" an alle Skripte anhängen:

require.config({
    urlArgs: "bust=v2"
});

Für Entwicklungszwecke können Sie Forderung erzwingen, den Cache zu umgehen, indem Sie einen Zeitstempel anhängen:

require.config({
    urlArgs: "bust=" + (new Date()).getTime()
});

Andere Tipps

Verwenden Sie dafür keine Urlargs!

Erfordernder Skript lädt Respekt. HTTP Caching Header. (Skripte werden mit einem dynamisch eingefügten geladen <script>, Dies bedeutet, dass die Anfrage genauso aussieht wie jedes alte Vermögenswert.)

Servieren Sie Ihre JavaScript -Vermögenswerte mit den richtigen HTTP -Headern, um das Caching während der Entwicklung zu deaktivieren.

Die Verwendung von URLARGs von Request bedeutet, dass alle von Ihnen festgelegten Haltepunkte nicht über Aktualisierungen erhalten bleiben. Sie müssen am Ende setzen debugger Aussagen überall in Ihrem Code. Schlecht. ich benutze urlArgs Für Cache-Busting-Vermögenswerte während der Produktionsverbesserung mit dem Git SHA; Dann kann ich meine Vermögenswerte für immer zwischengespeichert und garantiert nie abgestandene Vermögenswerte haben.

In der Entwicklung verspotte ich alle Ajax -Anfragen mit einem Komplex Mockjax Konfiguration, dann kann ich meine App im JavaScript-Modus mit a bedienen 10 Line Python HTTP -Server mit allen ausgeschalteten Caching. Dies hat sich für mich zu einer ziemlich großen "Enterprisey" -Anwendung mit Hunderten von Rastful -Webservice -Endpunkten vergrößert. Wir haben sogar einen vertraglichen Designer, der mit unserem echten ProduktionscodeBase arbeiten kann, ohne ihm Zugriff auf unseren Backend -Code zu gewähren.

Die Urlargs -Lösung hat Probleme. Leider können Sie nicht alle Proxy -Server steuern, die möglicherweise zwischen Ihnen und dem Webbrowser Ihres Benutzers liegen. Einige dieser Proxy -Server können leider so konfiguriert werden, dass URL -Parameter beim Zwischenspeichern von Dateien ignoriert werden. In diesem Fall wird die falsche Version Ihrer JS -Datei an Ihren Benutzer geliefert.

Ich gab endlich auf und implementierte meine eigene Fix direkt in fordern.js. Wenn Sie bereit sind, Ihre Version der Forderungsbibliothek zu ändern, kann diese Lösung für Sie funktionieren.

Sie können den Patch hier sehen:

https://github.com/jbcpollak/requirejs/commit/589ee0CDFE6F719CD761EEEE631CE68EEE09A5A67

Sobald Sie hinzugefügt sind, können Sie so etwas in Ihrer Erfordernisse konfigurieren:

var require = {
    baseUrl: "/scripts/",
    cacheSuffix: ".buildNumber"
}

Verwenden Sie Ihre Build -System- oder Serverumgebung, um zu ersetzen buildNumber mit einer Revisions -ID / Softwareversion / Lieblingsfarbe.

Verwenden Sie ein solches Gebrauch:

require(["myModule"], function() {
    // no-op;
});

Erforderlich, diese Datei anzufordern:

http://yourserver.com/scripts/myModule.buildNumber.js

In unserer Serverumgebung verwenden wir URL -Umschreiben -Regeln, um die BuildNumber auszuziehen und die richtige JS -Datei zu bedienen. Auf diese Weise müssen wir uns eigentlich keine Sorgen machen, alle unsere JS -Dateien umzubenennen.

Der Patch ignoriert jedes Skript, das ein Protokoll angibt, und wirkt sich nicht auf Nicht-JS-Dateien aus.

Dies funktioniert gut für meine Umgebung, aber ich ist mir klar, dass einige Benutzer ein Präfix und nicht ein Suffix bevorzugen würden. Es sollte einfach sein, mein Commit für Ihren Bedürfnissen zu ändern.

Aktualisieren:

In der Diskussion für Pull -Anfrage schlägt der Anforderungsautor vor, dass dies als Lösung zum Präfix der Revisionsnummer wirkt:

var require = {
    baseUrl: "/scripts/buildNumber."
};

Ich habe das nicht versucht, aber die Implikation ist, dass dies die folgende URL anfordern würde:

http://yourserver.com/scripts/buildNumber.myModule.js

Was für viele Menschen, die ein Präfix verwenden können, sehr gut funktionieren.

Hier sind einige mögliche doppelte Fragen:

Forderung und Proxy -Caching

fordern.js - Wie kann ich eine Version auf erforderlichen Modulen als Teil der URL festlegen?

Inspiriert von Leitern Sie den Cache auf Request.js Data-Main Wir haben unser Bereitstellungsskript mit der folgenden Ameisenaufgabe aktualisiert:

<target name="deployWebsite">
    <untar src="${temp.dir}/website.tar.gz" dest="${website.dir}" compression="gzip" />       
    <!-- fetch latest buildNumber from build agent -->
    <replace file="${website.dir}/js/main.js" token="@Revision@" value="${buildNumber}" />
</target>

Wo der Beginn von Main.js aussieht:

require.config({
    baseUrl: '/js',
    urlArgs: 'bust=@Revision@',
    ...
});

In Produktion

urlArgs Kann Probleme verursachen!

Der Hauptautor von RefordeJs bevorzugt es nicht zu verwenden urlArgs:

Für bereitgestellte Vermögenswerte ziehe ich es vor, die Version oder den Hash für den gesamten Build als Build -Verzeichnis zu setzen, und ändern Sie dann einfach die baseUrl Konfiguration, die für das Projekt verwendet wird, um dieses versionierte Verzeichnis als das zu verwenden baseUrl. Dann ändern sich keine anderen Dateien und es hilft zu vermeiden Einige Proxy -Probleme, bei denen sie eine URL möglicherweise nicht mit einer Abfragezeichenfolge zwischenspeichern.

Styling Mine.

Ich folge diesem Rat.

In Entwicklung

Ich bevorzuge einen Server, der Dateien intelligent zwischengespeichert, die sich häufig ändern können: einen Server, der emittiert Last-Modified und reagiert auf If-Modified-Since mit 304 gegebenenfalls. Sogar ein Server basierend auf Knotens ausdrücken SET SEITEN STATISCHE FILDEN DIES DAS GEBRAUCH DIE BOX. Es erfordert nichts mit meinem Browser und durchfällt keine Breakpoints.

Ich nahm diesen Ausschnitt aus Askapache und setzen Sie es in eine separate .conf -Datei meines lokalen Apache -Webservers (in meinem Fall /etc/apache2/other/preventcaching.conf) ein:

<FilesMatch "\.(html|htm|js|css)$">
FileETag None
<ifModule mod_headers.c>
Header unset ETag
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
Header set Pragma "no-cache"
Header set Expires "Wed, 11 Jan 1984 05:00:00 GMT"
</ifModule>
</FilesMatch>

Für die Entwicklung funktioniert dies einwandfrei, ohne den Code zu ändern. Was die Produktion betrifft, könnte ich den Ansatz von @dvtoevers verwenden.

Schnelle Lösung für die Entwicklung

Für die Entwicklung könnten Sie nur Deaktivieren Sie den Cache in Chrome Dev Tools (Deaktivieren von Chrom -Cache für die Website der Website deaktivieren). Die Cache -Deaktivierung erfolgt nur, wenn das Dialogfeld Dev Tools geöffnet ist. Sie müssen sich also keine Sorgen machen, wenn Sie diese Option jedes Mal umschalten, wenn Sie regelmäßig stöbern.

Hinweis: Verwenden Sie 'Urlargs'Ist die richtige Lösung in der Produktion, damit Benutzer den neuesten Code erhalten. Aber es erschwert das Debuggen, weil Chrome Breakpoints mit jeder Aktualisierung ungültig macht (weil es jedes Mal eine "neue" Datei serviert wird).

Ich empfehle nicht 'zu verwenden'Urlargs'Für Cache, die mit Anforderungen platzen. Da dies das Problem nicht vollständig löst. Die Aktualisierung einer Version NO führt zum Herunterladen aller Ressourcen, obwohl Sie nur eine einzige Ressource geändert haben.

Um dieses Problem zu behandeln, empfehle ich die Verwendung von Grunzmodulen wie "fileRev" zur Erstellung von Revisionsnummer. Darüber hinaus habe ich eine benutzerdefinierte Aufgabe in Gruntfile geschrieben, um die Überarbeitung von der Überarbeitung zu aktualisieren, wo immer dies erforderlich ist.

Bei Bedarf kann ich das Code -Snippet für diese Aufgabe freigeben.

So mache ich es in Django / Flask (kann leicht an andere Sprachen / VCS -Systeme angepasst werden):

In deiner config.py (Ich benutze dies in Python3, also müssen Sie möglicherweise die Codierung in Python2 optimieren)

import subprocess
GIT_HASH = subprocess.check_output(['git', 'rev-parse', 'HEAD']).strip().decode('utf-8')

Dann in Ihrer Vorlage:

{% if config.DEBUG %}
     require.config({urlArgs: "bust=" + (new Date().getTime())});
{% else %}
    require.config({urlArgs: "bust=" + {{ config.GIT_HASH|tojson }}});
{% endif %}
  • Erfordert keinen manuellen Build -Prozess
  • Nur läuft git rev-parse HEAD Einmal, wenn die App startet und speichert sie in der config Objekt

Dynamische Lösung (ohne Urlargs)

Es gibt eine einfache Lösung für dieses Problem, sodass Sie für jedes Modul eine eindeutige Revisionsnummer laden können.

Sie können die ursprüngliche RequiredJs.Load -Funktion speichern, sie mit Ihrer eigenen Funktion überschreiben und Ihre geänderte URL erneut an die ursprüngliche Anforderung analysieren: LOAD:

var load = requirejs.load;
requirejs.load = function (context, moduleId, url) {
    url += "?v=" + oRevision[moduleId];
    load(context, moduleId, url);
};

In unserem Bauprozess habe ich "Gulp-rev" verwendet, um eine Manifestdatei mit allen Modulen zu erstellen, die gebraucht werden. Vereinfachte Version meiner Gulp -Aufgabe:

gulp.task('gulp-revision', function() {
    var sManifestFileName = 'revision.js';

    return gulp.src(aGulpPaths)
        .pipe(rev())
        .pipe(rev.manifest(sManifestFileName, {
        transformer: {
            stringify: function(a) {
                var oAssetHashes = {};

                for(var k in a) {
                    var key = (k.substr(0, k.length - 3));

                    var sHash = a[k].substr(a[k].indexOf(".") - 10, 10);
                    oAssetHashes[key] = sHash;
                }

                return "define([], function() { return " + JSON.stringify(oAssetHashes) + "; });"
            }
        }
    }))
    .pipe(gulp.dest('./'));
});

Dies generiert ein AMD-Modul mit Revisionsnummern für Modulennamen, die als "Orevision" im Main.js enthalten sind, in dem Sie die Funktion der Anforderungsladung wie zuvor gezeigt überschreiben.

Dies gilt zusätzlich zu @Phil McCulls akzeptierter Antwort.

Ich verwende seine Methode, automatisiere den Prozess auch, indem ich eine T4-Vorlage erstelle, um vor dem Bau auszuführen.

Befehle vor dem Bau:

set textTemplatingPath="%CommonProgramFiles(x86)%\Microsoft Shared\TextTemplating\$(VisualStudioVersion)\texttransform.exe"
if %textTemplatingPath%=="\Microsoft Shared\TextTemplating\$(VisualStudioVersion)\texttransform.exe" set textTemplatingPath="%CommonProgramFiles%\Microsoft Shared\TextTemplating\$(VisualStudioVersion)\texttransform.exe"
%textTemplatingPath% "$(ProjectDir)CacheBuster.tt"

enter image description here

T4 -Vorlage:

enter image description here

Generierte Datei:enter image description here

Speichern Sie in Variable vor Anforderung.config.js wird geladen:enter image description here

Referenz in fordern.config.js:

enter image description here

In meinem Fall wollte ich jedes Mal, wenn ich klicke, das gleiche Formular laden, ich wollte nicht, dass die Änderungen, die ich in der Datei bleibt. Für diesen Beitrag ist es möglicherweise nicht relevant, aber dies könnte eine potenzielle Lösung auf der Client -Seite sein, ohne die Konfiguration für den Anforderungen festzulegen. Anstatt den Inhalt direkt zu senden, können Sie eine Kopie der erforderlichen Datei erstellen und die tatsächliche Datei intakt halten.

LoadFile(filePath){
    const file = require(filePath);
    const result = angular.copy(file);
    return result;
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top