Работник сервиса skipWaiting не может активировать ожидающее в настоящий момент ПО
Описание:
Мы используем предварительный кэш sw для кэширования сценариев заранее, поэтому для обновления сценариев мы даем возможность перезагрузки, потому что мы слушаем сообщение работника, чтобы пропустить ожидание вновь установленного работника службы по неизвестной причине, мы не получаем правильную информацию
importScript
// GETTING OLD SW reference (self) and NOT getting newly installed SW reference
self.addEventListener('message', function(event) {
*// not working*
self.skipWaiting();
});
// But if we put skipWaiting() in 'install' listener
// it is getting correct new SW reference and working correctly
self.addEventListener('install', function(event) {
// self.skipWaiting();
});
Регистрация SW
if('serviceWorker' in window.navigator) {
window.addEventListener('load', function() {
window.navigator.serviceWorker.register("/serviceWorker.js").then(function(registration) {
console.log("ServiceWorker registration successful with scope: ", registration);
registration.onupdatefound = function() {
console.log('NEW WILD WORKER HAS SPAWNED.!', registration);
var installedWorker = registration.installing;
installedWorker.onstatechange = function() {
if (installedWorker.state === 'installed') {
if (navigator.serviceWorker.controller) {
console.log('Updated content is available RELOAD!', navigator.serviceWorker.controller);
var el = document.getElementById('feature');
el.style['display'] = 'block';
}
}
}
}
}).catch(function(error) {
console.error("ServiceWorker registration failed: ", error);
});
});
window.navigator.serviceWorker.addEventListener('controllerchange', function() {
console.log('SERVICE WORKER UPDATED');
});
}
Конфигурация веб-пакета
new SWPrecacheWebpackPlugin({
cacheId: 'pwa',
filename: 'serviceWorker.js',
staticFileGlobsIgnorePatterns: [/\.map$/, /\.json$/, /_nch\.[0-9a-z]+\.[js, css]+/g, /webpackManifest\.[0-9a-z]+\.js/g, /.DS_Store\.[0-9a-z]+/g],
importScripts: ['offline/offline.1a2b3c4df1.js'],
dontCacheBustUrlsMatching: /./,
minify: false,
skipWaiting: false,
runtimeCaching: [ {
urlPattern: /_nch\.[0-9a-z]+\.[js, css]+/g,
handler: 'fastest',
options: {
cache: {
name: 'jd-internal-script',
maxEntries: 10,
},
},
}, {
urlPattern: /webpackManifest\.[0-9a-z]+\.js/g,
handler: 'networkFirst',
options: {
cache: {
name: 'jd-root-doc',
},
},
}],
}),
2 ответа
Лучшая документация для skipWaiting()
можно найти по адресу https://developers.google.com/web/fundamentals/instant-and-offline/service-worker/lifecycle
Вы можете назвать это безоговорочно в install
обработчик, или следуйте модели, которую вы, кажется, делаете, то есть слушать message
событие и звонок skipWaiting()
условно.
Если вы идете по условному маршруту, то вы должны изменить код своей клиентской страницы, чтобы правильно определить, когда работник службы, которого вы регистрируете, входит в waiting
и дать пользователю возможность взаимодействовать со страницей таким образом, чтобы postMessage()
сказать работнику сервиса skipWaiting()
, Исходя из того, что вы говорите, вы пробовали это, но похоже, что вы отправляете сообщение не тому экземпляру сервисного работника.
Вот как должен выглядеть код вашей страницы:
// On your page:
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('service-worker.js').then(function(reg) {
reg.onupdatefound = function() {
var newSW = reg.installing;
newSW.onstatechange = function() {
if (newSW.state === 'waiting') {
// This assumes there's a button with id='skip-waiting-button' that
// users should click to get the new SW to activate immediately.
var button = document.querySelector('#skip-waiting-button');
button.addEventListener('click', function() {
newSW.postMessage('skipWaiting');
});
// Assume that 'display' is 'none' initially.
button.style.display = 'inline';
}
// Handle whatever other SW states you care about, like 'active'.
};
};
})
});
}
// In your service worker:
self.addEventListener('message', event => {
if (event.data === 'skipWaiting') {
self.skipWaiting();
}
});
Итак, вот что я думаю... Ваш новый сервисный работник все еще ждет... следовательно, прослушиватель событий все еще находится на вашем старшем сервисном работнике... любые отправленные вами сообщения все равно будут перехватываться старым sw (так как новый ожидает),
В случае, если ваш единственный случай - заставить нового sw действовать, вы можете просто обновить страницу вместо отправки сообщения