63 votes

La mise en cache avec CRA React

Lorsque j'ai mis à jour mon site, que j'ai exécuté npm run build et que j'ai téléchargé les nouveaux fichiers sur le serveur, j'ai toujours l'ancienne version de mon site.

Sans React, je peux voir la nouvelle version de mon site avec le cache-busting. Je fais ça :

Dossier précédent

<link rel="stylesheet" href="http://stackoverflow.com/css/styles.css">

Nouveau dossier

<link rel="stylesheet" href="http://stackoverflow.com/css/styles.css?abcde">

Comment puis-je faire quelque chose comme ça ou pour réaliser le cache busting avec create react app ?

Il y a de nombreux fils de discussion dans le GitHub de create react app à ce sujet mais personne n'a de réponse appropriée/simple.

0 votes

C'est l'un des moyens de résoudre le problème de la disparition des caches : dev.to/mnathani/how-to-cache-bust-frontend-app-132l

58voto

Kerry Gougeon Points 857

EDIT : create-react-app v2 a maintenant le service worker désactivé par défaut.

Cette réponse ne s'applique qu'à CRA v1

Cela est probablement dû à votre travailleur web.

Si vous regardez dans votre fichier index.js, vous pouvez voir

registerServiceWorker();

Vous ne vous êtes jamais demandé ce qu'il faisait ? Si nous regardons le fichier à partir duquel il a été importé, nous pouvons voir que

// In production, we register a service worker to serve assets from local cache.

// This lets the app load faster on subsequent visits in production, and gives
// it offline capabilities. However, it also means that developers (and users)
// will only see deployed updates on the "N+1" visit to a page, since previously
// cached resources are updated in the background.

// To learn more about the benefits of this model, read {URL}
// This link also includes instructions on opting out of this behavior.

Si vous voulez supprimer le web worker, ne vous contentez pas de supprimer la ligne. Importez unregister et appelez-le dans votre fichier à la place du register.

import { unregister } from './registerServiceWorker';

et ensuite appeler

unregister()

P.S. Lorsque vous vous désinscrivez, il vous faudra au moins un rafraîchissement pour que cela fonctionne.

0 votes

"il faudra au moins un rafraîchissement pour que cela fonctionne" vous voulez dire qu'après le deuxième rafraîchissement l'utilisateur pourra voir le nouveau contenu ?

0 votes

@Alfrex92 oui, il devrait.

0 votes

Existe-t-il une autre solution ? L'utilisateur ne doit rafraîchir qu'une seule fois.

15voto

Ryan Chu Points 655

J'ai eu le même problème lorsque j'ai utilisé create-react-app ( et déployer sur heroku). Il continue à montrer l'ancienne version de mon application.

J'ai trouvé que le problème semble être du côté du navigateur, il met en cache mes anciennes versions. index.html avec son paquet de js périmé

Vous pouvez ajouter le texte suivant à votre en-tête de réponse côté serveur

"Cache-Control": "no-store, no-cache"

ou si vous utilisez également heroku create-react-app-buildpack , mettre à jour le static.json fichier

"headers": { 
    "/**": { 
        "Cache-Control": "no-store, no-cache" 
    } 
}

Je pense que de cette façon, vous pouvez toujours garder ce pauvre travailleur de service, et le dernier contenu sera affiché sur le chargement N+1 (deuxième rafraîchissement).

J'espère que cela vous aidera...

45 votes

Voulez-vous vraiment que tout soit sans cache ? C'est juste le fichier html qui est le coupable, non ?

0 votes

Peut-être que celle-ci est meilleure github.com/heroku/heroku-buildpack-static#custom-headers

14voto

bszom Points 314

Comme l'ont mentionné certaines des réponses précédentes, le travailleur de service et les en-têtes de cache (ou leur absence) peuvent conspirer contre vous lorsqu'il s'agit de voir d'anciennes versions de votre application React.

La documentation de React indique ce qui suit au sujet de mise en cache :

Utilisation de Cache-Control: max-age=31536000 pour votre build/static les actifs, et Cache-Control: no-cache pour tout le reste est un coffre-fort point de départ sûr et efficace qui garantit que le navigateur de votre utilisateur vérifiera toujours la présence d'une mise à jour index.html et mettra en cache toutes les l'adresse build/static pendant un an. Notez que vous pouvez utiliser l'expiration d'un d'un an sur build/static en toute sécurité car le contenu du fichier est incorporé dans le nom du fichier.

Comme l'a mentionné @squarism, les anciennes versions de create-react-app utilisaient par défaut l'option opt-out de l'enregistrement du travailleur de service, tandis que les versions plus récentes sont opt-in . Vous pouvez en savoir plus à ce sujet dans le documents officiels . Il s'agit d'un processus assez simple pour adapter votre configuration à la toute dernière version de l'application. modèle si vous avez commencé avec une ancienne version de create-react-app et que vous voulez passer au nouveau comportement.

Questions connexes :

4 votes

Merci d'être aussi complet, c'est la meilleure réponse pour mon scénario. Au cas où quelqu'un d'autre essaierait de s'assurer que Cloudfront délivre toujours l'application la plus récente à partir de S3, il semble que la solution consiste à configurer les éléments suivants Cache-Control: max-age=0 sur le index.html dans le seau du site web.

1 votes

@bszom comment définir un Cache-Control : no-cache pour build/static vs index.html. Existe-t-il une propriété sur la balise méta pour cela ?

0 votes

@A.com Cache-Control est un en-tête de réponse HTTP et n'est pas lié aux balises méta. La façon dont vous configurez ce paramètre dépend de la façon dont vous servez/hébergez votre application.

2voto

squarism Points 1280

Il semble qu'ils soient passés de l'opt-out à l'opt-in en ce qui concerne le travailleur social. Voici le commit qui a modifié le README et qui contient des exemples similaires à la réponse de Kerry G :

https://github.com/facebook/create-react-app/commit/1b2813144b3b0e731d8f404a8169e6fa5916dde4#diff-4e6ec56f74ee42069aac401a4fe448ad

2voto

Si votre problème concerne des ressources référencées de manière statique dans index.html, comme des fichiers .css ou des fichiers .js supplémentaires (par exemple, des fichiers de configuration), vous pouvez déclarer une variable d'environnement React, lui attribuer une valeur unique et la référencer dans votre fichier index.html.

Dans votre build script (bash) :

REACT_APP_CACHE_BUST={e.g. build number from a CI tool} npm run build

Dans votre index.html :

<link rel="stylesheet" href="%PUBLIC_URL%/index.css?cachebust=%REACT_APP_CACHE_BUST%" />

Le nom de la variable doit commencer par REACT_APP_. Plus d'informations sur les variables d'environnement dans React : https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables .

0 votes

Qu'en est-il de notre code javascript et du code HTML, car ils ne sont pas ajoutés lorsque je télécharge mon nouveau code ?

1 votes

Désolé pour la réponse tardive. Je pense que la situation de javascript dépend de votre processus de construction. Nous utilisons create-react-app (l'entrée package.json -> scripts -> build est 'react-scripts build'). Le processus de build génère les fichiers javascript et les noms des fichiers incluent un hash du contenu du fichier. Donc, en général, il n'y a pas besoin de casser le cache pour les fichiers js, je pense. Si votre fichier html d'index est mis en cache, alors le problème pourrait être dans le contrôle du cache du serveur web.

0 votes

Merci, Michal, pour votre réponse. Michal, pouvez-vous m'aider à gérer le contrôle du cache du serveur web car mon application react est sur un serveur séparé et le serveur Express.js (Node.js) est sur un serveur différent.

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