Cache expirant sur require.js de données principale

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 pré & post packaging, mais je rencontre beaucoup de problèmes lorsque chrome & mobile safari s'accroche à la version en cache du client.js. J'aimerais ajouter un cachebuster au 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 require essaie d'obtenir le client.js de / , pas /js , afin d'erreur 404.

j'ai aussi essayé d'ajouter

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

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

j'ai aussi essayé d'ajouter la même valeur à app.build.js , mais quand il est là, R. js ne concaténue plus mes fichiers js, il les humilie.

Quelle est la syntaxe appropriée pour désactiver un require.js de données principale du script de cache?

40
demandé sur Jesse 2012-06-18 22:34:25

2 réponses

Comment définissez-vous Votre Exigence.config? Je pense que pour qu'il prenne effet avant d'importer besoin.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é "requiert" doit être construit avant d'importer besoin.js.

mise à JOUR

comme Jesse le souligne dans les commentaires ci-dessous, il y a quelques améliorations que vous devriez appliquer à votre{} objet require pour la production utiliser. L'exemple ci-dessus est tiré de la documentation Requerjs et modifié le moins possible pour répondre à cette question.

voici quelques éléments à prendre en considération pour la production:

  • au lieu d'utiliser la date-heure actuelle comme variable de mise en cache, vous devriez utiliser un numéro de build à partir de votre environnement de développement. Cela permet à vos clients de mettre en cache le Javascript entre les versions, mais les poussera à rafraîchir leur cache. chaque fois que vous faites une mise à jour du logiciel.
  • Jesse utilise aussi la capacité require {} de spécifier des 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.
  • Réglez le temps d'attente en fonction de vos besoins. J'ai utilisé la valeur d'exemple 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>

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

UPDATE 2

la solution de buste de 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 mandataires peuvent être malheureusement configuré 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 livré à votre utilisateur.

je recommande d'utiliser un buildNumber dans votre requête de nom de fichier Javascript, comme buildNumber.myModule.js (préfixe) ou myModule.buildNumber.js (postfix). Vous pouvez utiliser le style du préfixe en modifiant le baseUrl:

baseUrl: "/scripts/buildNumber",

noter l'absence d'un '/' à la fin du baseUrl.

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

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

73
répondu JBCP 2017-05-23 12:18:17

voici ma solution (en cas d'urgence) :

  1. trouver le code suivant dans require.js:

version de développement

//Join the path parts together, then figure out if baseUrl is needed.
url = syms.join('/');
url += (ext || (/^data\:|^blob\:|\?/.test(url) || skipExt ? '' : '.js'));
url = (url.charAt(0) === '/' || url.match(/^[\w\+\.\-]+:/) ? '' : config.baseUrl) + url;

ou

version de Production

e).join("/"),h=m(d,h)){H(h)&&(h=h[0]);a.splice(0,e,h);break}d=a.join("/");d+=b||(/^data\:|\?/.test(d)||c?"":".js");
  1. et ajouter ?v=x.0 après .js

    url += (ext || (/^data\:|^blob\:|\?/.test(url) || skipExt ? '' : '.js?v=1.0'));

    ou

    (/^data\:|\?/.test(d)||c?"":".js?v=1.0");

-2
répondu Alexee 2017-01-09 10:02:11