J'aimerais que les utilisateurs puissent se mettre à jour sur place lorsqu'un nouveau technicien est disponible et attend? Je suis déjà en mesure d'afficher une fenêtre contextuelle lorsqu'une nouvelle mise à jour est disponible, mais je voudrais ajouter un bouton pour forcer la mise à jour sur place. Je comprends que cela peut être réalisé en appelant skipWaiting mais je ne sais pas comment l'implémenter avec une application Create React. Quelqu'un peut-il y parvenir? Je vous serais reconnaissant de l'aide. Merci!
J'ai utilisé un package appelé https://github.com/bbhlondon/cra-append-sw pour ajouter le code suivant pour appeler le déclencheur skipWaiting:
self.addEventListener('message', event => {
if (event.data === 'skipWaiting') {
self.skipWaiting();
}
});
Dans serviceWorker.js le fichier peut trouver ce code
if (config && config.onUpdate) {
config.onUpdate(registration);
}
Alors implémentez la fonction config.onUpdate
Créer un fichier swConfig.js
export default {
onUpdate: registration => {
registration.unregister().then(() => {
window.location.reload()
})
},
onSuccess: registration => {
console.info('service worker on success state')
console.log(registration)
},
}
À index.js envoyer la fonction d'implémentation à serviceWorker
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import swConfig from './swConfig'
ReactDOM.render(<App />,
document.getElementById('root'));
serviceWorker.register(swConfig);
Découvrez ce dépôt https://github.com/wgod58/create_react_app_pwaupdate
L'ARC build\service-worker.js
le fichier maintenant (v3 plus) inclut le code pour gérer skipWaiting
:
self.addEventListener('message', (event) => {
if (event.data && event.data.type === 'SKIP_WAITING') {
self.skipWaiting();
}
});
La fonction de registre serviceWorker.js
fichier appelé dans index.js
accepte désormais un paramètre de configuration:
serviceWorker.register({
onUpdate: registration => {
const waitingServiceWorker = registration.waiting
if (waitingServiceWorker) {
waitingServiceWorker.addEventListener("statechange", event => {
if (event.target.state === "activated") {
window.location.reload()
}
});
waitingServiceWorker.postMessage({ type: "SKIP_WAITING" });
}
}
});
Cela sautera l'attente, puis actualisera la page une fois la mise à jour appliquée.
Je sais qu'il a été répondu, mais j'ai trouvé une solution qui ne nécessite pas de packages supplémentaires, sauf la boîte de travail bien sûr.
au package.json:
"build": "react-scripts build && node ./src/serviceWorkerBuild"
serviceWorkerBuild.js
const workboxBuild = require('workbox-build');
// NOTE: This should be run *AFTER* all your assets are built
const buildSW = () => {
// This will return a Promise
return workboxBuild.injectManifest({
swSrc: 'src/serviceWorkerRules.js',
swDest: 'build/sw.js',
globDirectory: 'build',
globPatterns: [
'**\/*.{js,css,html,png}',
]
}).then(({count, size, warnings}) => {
// Optionally, log any warnings and details.
warnings.forEach(console.warn);
console.log(`${count} files will be precached, totaling ${size} bytes.`);
});
};
buildSW();
et serviceWorkerRules.js où vous pouvez ajouter vos règles:
importScripts(
'https://storage.googleapis.com/workbox-cdn/releases/3.5.0/workbox-sw.js'
);
/* global workbox */
if (workbox) {
console.log('Workbox is loaded');
self.addEventListener('install', event => {
self.skipWaiting();
});
/* injection point for manifest files. */
workbox.precaching.precacheAndRoute([]);
/* custom cache rules*/
workbox.routing.registerNavigationRoute('/index.html', {
blacklist: [/^\/_/, /\/[^\/]+\.[^\/]+$/],
});
workbox.routing.registerRoute(
/\.(?:png|gif|jpg|jpeg|svg)$/,
workbox.strategies.cacheFirst({
cacheName: 'images',
plugins: [
new workbox.expiration.Plugin({
maxEntries: 60,
maxAgeSeconds: 5 * 24 * 60 * 60, // 5 Days
}),
],
}),
);
Ajoutez également window.location.reload();
à serviceWorker.js à la ligne # 78.
la réponse de @ user10532439 n'a pas fonctionné pour moi. J'ai fini par utiliser https://github.com/bbhlondon/cra-append-sw et à ajouter
// @ts-ignore
workbox.skipWaiting();
// @ts-ignore
workbox.clientsClaim();
de même que
"build": "react-scripts build && cra-append-sw -s ./src/custom-sw.js",
Vous devez appeler la méthode skipWaiting dans l'événement d'installation de l'agent de service. Le technicien de service est découplé du code UI/React. Donc, rien à voir avec vraiment réagir.
En ce moment, j'ai un modèle où j'ai refactorisé le code d'événement d'installation à sa propre méthode, donc mes techniciens de service ont tendance à ressembler à ceci:
self.addEventListener( "install", function ( event ) {
event.waitUntil( installServiceWorker() );
} );
function installServiceWorker() {
self.skipWaiting();
// do stuff here like pre-caching site core assets
//most likely returning a promise
}
Aussi: n'appelez pas skipWaiting si vous avez besoin de synchroniser les actifs mis en cache avec l'interface utilisateur active. Si votre technicien de service est en cours de mise à jour et pourrait éventuellement casser l'interface utilisateur, n'appelez pas skipWaiting. Attendez plutôt que l'utilisateur actualise la page. Vous pouvez utiliser l'infrastructure de messagerie pour informer l'utilisateur qu'une mise à jour est disponible et l'actualiser à titre d'exemple.