web-dev-qa-db-fra.com

Expirer le cache sur data-main require.js

J'utilise require.js et r.js pour empaqueter mes modules AMD. J'utilise jquery & requirejs via la syntaxe suivante:

<script data-main="/js/client" src="/js/external/require-jquery.js"></script>

Tout cela fonctionne très bien avant et après le packaging, mais je rencontre beaucoup de problèmes où chrome et safari mobile s'accrochent à la version mise en cache de client.js. Je voudrais ajouter un cachebuster à client.js, mais je n'arrive pas à comprendre comment le faire en utilisant la syntaxe ci-dessus.

J'ai essayé quelques variantes de:

<script data-main="js/client.js?b=busted" src="/js/external/require-jquery.js"></script>

mais maintenant il faut essayer d'obtenir client.js de /, ne pas /js, donc 404s.

J'ai aussi essayé d'ajouter

urlArgs : "bust="+new Date().getTime()

à require.config, mais il semble n'avoir aucun effet.

J'ai également essayé d'ajouter la même valeur à app.build.js, mais quand il est là-dedans, r.js ne concatène plus mes fichiers js, les uglifie simplement.

Quelle est la syntaxe appropriée pour supprimer un cache de script data-main require.js?

42
Jesse

Comment définissez-vous votre require.config? Je pense que pour qu'il prenne effet avant d'importer require.js, vous devez le coder comme ceci:

<script type="text/javascript">
    var require = {
        baseUrl: "/scripts/",
        waitSeconds: 15,
        urlArgs : "bust="+new Date().getTime()
    };
</script>
<script data-main="app/main" src="/scripts/require.js"></script>

Plus précisément, un objet nommé "require" doit être construit avant d'importer require.js.

[~ # ~] mise à jour [~ # ~]

Comme le souligne Jesse dans les commentaires ci-dessous, vous devez appliquer quelques améliorations à votre objet {} requis pour une utilisation en production. L'exemple ci-dessus est extrait de la documentation RequireJS et modifié le moins possible pour répondre à cette question.

Voici quelques éléments à considérer pour une utilisation en production:

  • Au lieu d'utiliser la date-heure actuelle comme variable de contournement du cache, vous devez utiliser un numéro de build de votre environnement de développement. Cela permet à vos clients de mettre en cache le Javascript entre les versions mais les obligera à actualiser leur cache chaque fois que vous effectuez une mise à jour logicielle.
  • Jesse utilise également la capacité de require {} pour spécifier les dépendances au lieu d'utiliser l'attribut data-main du script. Je ne sais pas si c'est strictement mieux, mais je pense que c'est plus propre.
  • Ajustez les waitSeconds en fonction de vos besoins. J'ai utilisé l'exemple de valeur de la documentation RequireJS, mais vous devez ajuster la valeur ou l'omettre, en fonction de vos besoins.

Donc, si vous appliquez ces techniques, votre code pourrait ressembler à:

<script type="text/javascript">
    var require = {
        baseUrl: "/scripts/",
        waitSeconds: 15,
        urlArgs : "bust="+{{buildNumber}},
        deps : ['app/main']
    };
</script>
<script src="/scripts/require.js?bust={{buildNumber}}"></script>

Notez que dans ce cas, {{buildNumber}} est une valeur fournie par le serveur.

MISE À JOUR 2

La solution de suppression du cache urlArgs a des problèmes. Malheureusement, vous ne pouvez pas contrôler tous les serveurs proxy qui pourraient se trouver entre vous et le navigateur Web de votre utilisateur. Certains de ces serveurs proxy peuvent malheureusement être configurés pour ignorer les paramètres d'URL lors de la mise en cache des fichiers. Si cela se produit, la mauvaise version de votre fichier JS sera remise à votre utilisateur.

Je recommanderais d'utiliser un buildNumber in votre demande de nom de fichier Javascript, comme buildNumber.myModule.js (préfixe) ou myModule.buildNumber.js (postfix). Vous pouvez utiliser le style de préfixe en modifiant la baseUrl:

baseUrl: "/scripts/buildNumber",

Notez l'absence d'un "/" à la fin de la baseUrl.

Vous devrez utiliser une version modifiée de require.js pour utiliser la solution postfix. Vous pouvez en savoir plus à ce sujet ici: https://stackoverflow.com/a/21619359/1017787

Évidemment, dans les deux cas, vous souhaiterez utiliser une solution pour remplacer buildNumber par un certain type de numéro de version qui change avec chaque version.

75
JBCP