302 votes

Prévenir RequireJS de mise en Cache des Scripts Requis

RequireJS semble faire quelque chose en interne qui met en cache les fichiers javascript nécessaires. Si je fais une modification à l'un des fichiers requis, j'ai renommer le fichier pour que les modifications soient appliquées.

Le truc commun de l'ajout d'un numéro de version, comme une chaîne de requête paramètre à la fin du nom de fichier ne fonctionne pas avec requirejs <script src="jsfile.js?v2"></script>

Ce que je recherche est un moyen de prévenir cette nouvelle mise en mémoire cache de RequireJS scripts requis sans avoir à renommer mes fichiers de script à chaque fois qu'ils sont mis à jour.

Solution Multi-Plateforme:

Je suis maintenant en utilisant urlArgs: "bust=" + (new Date()).getTime() automatique cache-busting au cours du développement et de l' urlArgs: "bust=v2" de la production là où je incrémenter la valeur codée en dur version num après le déploiement d'une mise à jour pour le scénario.

Note:

@Dustin Getz mentionné dans une récente réponse que Chrome Developer Tools déposez des points d'arrêt au cours de débogage lorsque les fichiers Javascript sont continuellement actualisées de ce genre. Une solution de contournement consiste à écrire debugger; dans le code pour déclencher un point d'arrêt dans la plupart des Javascript débogueurs.

Serveur De Solutions Spécifiques:

Pour des solutions spécifiques qui peuvent travailler mieux pour votre environnement de serveur, Noeud ou Apache, reportez-vous quelques réponses ci-dessous.

459voto

phil mccull Points 3484

RequireJS peut être configuré pour ajouter une valeur à chaque script url pour le cache busting.

À partir de la RequireJS documentation (http://requirejs.org/docs/api.html#config):

urlArgs: chaîne de requête Supplémentaires arguments ajouté à l'Url que RequireJS utilise pour récupérer des ressources. Le plus utile à cache buste lorsque le navigateur ou le serveur n'est pas configuré correctement.

Exemple, l'ajout d'une "v2" pour tous les scripts:

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

À des fins de développement, vous pouvez forcer RequireJS pour contourner le cache en ajoutant un timestamp:

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

54voto

Dustin Getz Points 8514

Ne pas utiliser urlArgs pour cette!

Besoin script charge relativement à la mise en cache http headers. (Les Scripts sont chargés avec un insérés dynamiquement <script>, ce qui signifie que la demande semble juste comme n'importe quel actif ancien consommer.)

Servir votre javascript actifs avec les en-têtes appropriés pour désactiver la mise en cache lors du développement.

À l'aide de require urlArgs signifie que tous les points d'arrêt vous définissez ne sera pas conservé dans le rafraîchit; vous finissez par avoir besoin de faire debugger états partout dans votre code. Mauvais. J'utilise urlArgs pour le cache-busting actifs au cours de la production des mises à niveau avec le git sha, alors je peux mettre mon actifs destinés à être mis en cache pour toujours et être assuré de n'avoir jamais obsolètes actifs.

En développement, j'ai moquer de toutes les requêtes ajax avec un complexe mockjax de configuration, puis je peux servir mon application en javascript-avec un 10 ligne python serveur http avec la mise en cache hors tension. Cela a mis à l'échelle pour moi un très grand "enterprisey" application avec des centaines de restful webservice points de terminaison. Nous avons même une contracté designer qui peut travailler avec notre réel de production de la base de code sans lui donner accès à notre backend code.

24voto

JBCP Points 2397

Le urlArgs solution a des problèmes. Malheureusement, vous ne pouvez pas contrôler tous les serveurs proxy qui peut être fait entre vous et votre navigateur web de l'utilisateur. Certains de ces serveurs proxy peuvent être malheureusement configuré pour ignorer les paramètres d'URL lors de la mise en cache de fichiers. Si cela se produit, la mauvaise version de votre fichier JS sera livré à votre utilisateur.

J'ai finalement abandonné et mis en œuvre mon propre correctif directement dans require.js. Si vous êtes prêt à modifier votre version de la requirejs de la bibliothèque, cette solution pourrait fonctionner pour vous.

Vous pouvez voir le patch ici:

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

Une fois ajouté, vous pouvez faire quelque chose comme ceci à votre besoin de config:

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

Utilisez votre système de construction ou d'environnement de serveur pour remplacer buildNumber avec une révision id / version de logiciel / couleur préférée.

À l'aide de besoin comme ceci:

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

Sera la cause de besoin à la demande de ce fichier:

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

Sur notre environnement de serveur, nous utilisons des règles de réécriture d'url à dépouiller le buildNumber, et de servir le bon fichier JS. De cette façon, nous n'avez pas à vous soucier de renommer l'ensemble de nos fichiers JS.

Le patch va ignorer tous les script qui spécifie un protocole, et elle n'affectera pas les non-JS fichiers.

Cela fonctionne bien pour mon environnement, mais je sais que certains utilisateurs préfèrent un préfixe plutôt que d'un suffixe, il devrait être facile à modifier mon engageons à répondre à vos besoins.

Mise à jour:

Dans la demande d'extraction de discussion, le requirejs auteur suggèrent que ce pourrait fonctionner comme une solution à préfixe du numéro de la révision:

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

Je n'ai pas essayé cela, mais l'implication est que ce serait de demander à l'URL suivante:

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

Qui pourrait très bien fonctionner pour beaucoup de gens qui peuvent utiliser un préfixe.

Voici quelques-unes des doublons de questions:

RequireJS et proxy de mise en cache

require.js - Comment puis-je mettre une version sur les modules nécessaires dans le cadre de l'URL?

19voto

dvtoever Points 1377

Inspiré par Expiration du cache sur require.js de données principale, nous avons mis à jour notre script de déploiement avec la tâche ant suivante:

<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>

D'où le début de main.js ressemble:

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

11voto

Louis Points 13534

Dans la production

urlArgs peut causer des problèmes!

L'auteur principal de requirejs préfère ne pas utiliser urlArgs:

Pour les moyens déployés, je préfère les mettre à la version ou de hachage pour l'ensemble de la construire un répertoire de construction, puis il suffit de modifier l' baseUrl config utilisé pour le projet afin de l'utiliser versionnées répertoire que l' baseUrl. Alors aucune autre modification des fichiers, et il permet d'éviter certains proxy de questions où ils ne peut pas mettre en cache une URL avec une chaîne de requête.

[Style de la mine.]

J'ai suivi ce conseil.

Dans le développement

Je préfère utiliser un serveur de façon intelligente met en cache des fichiers qui peuvent changer fréquemment: un serveur qui émet Last-Modified et répond à l' If-Modified-Since avec 304 le cas échéant. Même un serveur basé sur le Nœud de l' express de servir les fichiers statiques ce droit sorti de la boîte. Il ne nécessite pas de faire quoique ce soit sur mon navigateur, et de ne pas gâcher des points d'arrêt.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X