Кеширование файлов с помощью Webpack + Service Worker
Я работаю над проектом, который состоит из множества репозиториев. Один из них содержит JS-код приложения, другой - серверную часть, на которой хранится index.html.
У нас есть требование, чтобы наше приложение было доступно для работы в автономном режиме. Это было сделано уже с помощью функции appcache. Но в какой-то момент мы решили пойти дальше и использовать для этой функции Service Worker (SW).
Итак, моя история о том, как я добавил генерацию SW с помощью Webpack и решал проблемы (например, кеширование запросов cors, когда сервер не разрешает cors и т. Д.)
Во-первых, вы можете сохранить манифест appcache и одновременно использовать ПО. Браузер будет использовать ПО, если эта функция включена или не используется в кэше приложений.
Также обратите внимание, что ПО включено только через https. Если вы пишете и тестируете его на локальном сервере, хранящемся через http, вы можете сделать это (в FireFox): перейдите в
about: config
набор
devtools.serviceWorkers.testing.enabled = true
Теперь ПО будет работать с открытыми инструментами разработчика в FF.
Итак, откройте index.html и добавьте код, который будет регистрировать SW:
if ('serviceWorker' в навигаторе) {
navigator.serviceWorker.register (‘/ sw.js’)
.catch ((e) = ›{
выдать новую ошибку («Ошибка при регистрации сервис-воркера:» + e.message);
});
}
Следующий шаг - добавить генерацию ПО в конфигурацию webpack:
// импортировать плагины.
// WriteFilePlugin необходим для разрешения файловых файлов webpack в файловую систему.
// WorkboxPlugin содержит плагин, который будет генерировать ПО
const WriteFilePlugin = require («напишите-файл-webpack-плагин»);
const WorkboxPlugin = require (‘workbox-webpack-plugin’);
Самый общий код плагина генератора ПО:
function serviceWorkerConfig () {
возвращение {
плагины: [
новый WorkboxPlugin.GenerateSW ({
swDest: path.resolve (DIST_PATH, ‘/service-worker/sw.js’),
importsDirectory: path.resolve (DIST_PATH, ‘/ service-worker /’)
}),
новый WriteFilePlugin ()
]
};
}
swDest - установить путь к файлу sw.js
importsDirectory - укажите путь к файлу манифеста для предварительного кеширования (он создается автоматически)
Теперь мы можем добавить код, который заставляет SW кэшировать файлы или запросы:
новый WorkboxPlugin.GenerateSW ({
…
runtimeCaching: [
{
urlPattern: ‘/ offline-app? Forcew’,
обработчик: «networkFirst»,
опции: {
fetchOptions: {
режим: ‘no-cors’,
},
},
};
],
Это заставит SW обрабатывать все запросы ‘/ offline-app? Forcew’. ВНИМАНИЕ: ПО будет обрабатывать только запросы «/ offline-app? Forcew», но не запросы «/ offline-app». ПО чувствительно к параметрам запроса.
обработчик - описывает, какую стратегию использовать. «NetworkFirst» означает, что ПО всегда будет запрашивать ресурс и только при потере соединения будет принимать кэшированное значение.
fetchOptions.mode: «no-cors» означает, что ресурсы находятся в том же домене, что и SW.
Также мы можем кешировать запросы для некоторых api. И установите максимальный возраст кеша.
runtimeCaching: [
…
{
urlPattern: ‘https://someApi.example.com/….’,
обработчик: «cacheFirst»,
опции: {
fetchOptions: {
режим: «корс»,
},
cacheName: ‘cache-with-expiration’,
// в секундах
срок действия: 24 * 60 * 60,
},
Здесь мы использовали fetchOptions.mode: «cors», что означает, что ресурсы размещаются в другом домене, который разрешает запросы cors.
Также мы использовали параметр cacheName, который позволит SW хранить кеш в отдельной структуре и аннулировать его по истечении времени, установленного в параметре истечения срока.
Также я столкнулся с проблемой, когда мы не могли изменить настройки сервера, на котором хранятся изображения, чтобы разрешить запросы cors. Но выход есть:
runtimeCaching: [
…
{
urlPattern: ‘https://someServer.example.com/….’,
обработчик: «cacheFirst»,
опции: {
fetchOptions: {
режим: ‘no-cors’,
},
cacheableResponse: {статусы: [0, 200]}
},
Когда ПО делает запрос к серверу, который не поддерживает cors, ответ имеет статус 0. Это непрозрачный ответ. И ПО не может их кэшировать. Но если вы уверены, что ответ будет правильным и не вернет 500 или иначе, вы можете принудительно кэшировать его, используя fetchOptions.mode: ‘no-cors’ и cacheableResponse: {statuses: [0, 200]}.
И последнее: когда вы развертываете новую версию ПО и хотите принудительно активировать ПО, как только пользователь перезагружает страницу, вы можете использовать skipWaiting: true:
плагины: [
новый WorkboxPlugin.GenerateSW ({
swDest: path.resolve (DIST_PATH, ‘/service-worker/sw.js’),
importsDirectory: path.resolve (DIST_PATH, ‘/ service-worker /’),
skipWaiting: правда,
runtimeCaching: […]
}
…
Это все.