В Workbox ключевым элементом расширяемости и настройки кэширования являются плагины. Плагины позволяют вмешиваться в жизненный цикл запроса и ответа, добавлять логику обработки ошибок, управление заголовками, условное кэширование и многое другое. Когда в маршруте применяется несколько плагинов, крайне важно понимать порядок их вызова, так как он влияет на поведение сервиса и конечный результат обработки.
Workbox определяет несколько основных точек вызова плагинов:
requestWillFetch – вызывается перед
отправкой запроса на сервер.cacheKeyWillBeUsed – позволяет
изменить ключ кэша перед проверкой наличия ресурса в кэше.cacheWillUpdate – определяет, должен
ли ответ сохраняться в кэш и каким образом.cachedResponseWillBeUsed – вызывается
перед возвратом ответа из кэша.fetchDidSucceed – вызывается после
успешного сетевого запроса.fetchDidFail – вызывается при ошибке
сетевого запроса.Каждая из этих точек может быть расширена несколькими плагинами одновременно, и порядок их применения строго определен.
requestWillFetchПлагины в массиве вызываются в том порядке, в котором они
перечислены при создании маршрута. Первый плагин получает
исходный объект Request, затем каждый последующий получает
результат предыдущего плагина.
workbox.routing.registerRoute(
'/api/',
new workbox.strategies.NetworkFirst({
plugins: [pluginA, pluginB, pluginC]
})
);
В этом примере:
pluginA.requestWillFetch(request)pluginB.requestWillFetch(modifiedRequestA)pluginC.requestWillFetch(modifiedRequestB)Если какой-либо плагин возвращает новый Request, он
используется дальше.
cacheKeyWillBeUsedЭтот хук позволяет модифицировать ключ кэша, что важно для реализации версионирования ресурсов или различий кэша по заголовкам. Последовательность вызова здесь такая же — по порядку. Возвращаемое значение предыдущего плагина передается следующему.
Пример использования:
const cacheKeyPlugin = {
cacheKeyWillBeUsed: async ({request, mode}) => {
if (request.url.includes('v2')) {
return new Request(request.url + '?v=2');
}
return request;
}
};
Если несколько плагинов меняют ключ кэша, изменения будут последовательно накапливаться.
cacheWillUpdateЭтот хук используется для фильтрации и модификации ответов перед сохранением в кэш. В отличие от предыдущих хуков, порядок применения плагинов идёт в прямом порядке, и результат первого плагина может быть отклонен следующим.
const statusPlugin = {
cacheWillUpdate: async ({response}) => {
return response.status === 200 ? response : null;
}
};
Если один плагин вернёт null, последующие плагины могут
его изменить или также вернуть null, что приведет к
пропуску записи в кэш.
cachedResponseWillBeUsedЭтот хук применяется при получении ответа из кэша, и порядок его вызова обратный:
Пример:
const logPlugin = {
cachedResponseWillBeUsed: async ({cachedResponse}) => {
console.log('Используется кэш:', cachedResponse);
return cachedResponse;
}
};
fetchDidSucceed
и fetchDidFailfetchDidSucceed вызывается после успешного
сетевого запроса, и плагины обрабатываются в прямом
порядке.fetchDidFail срабатывает при сбое запроса и также
вызывается по порядку, что позволяет реализовать
цепочку резервного кэширования или логирование ошибок.workbox.routing.registerRoute(
({url}) => url.pathname.startsWith('/api/'),
new workbox.strategies.NetworkFirst({
cacheName: 'api-cache',
plugins: [
{
requestWillFetch: async ({request}) => {
const modified = new Request(request, {
headers: {...request.headers, 'X-Custom': '1'}
});
return modified;
}
},
{
cacheKeyWillBeUsed: async ({request}) => {
return new Request(request.url + '?cache=true');
}
},
{
cacheWillUpdate: async ({response}) => {
return response.status === 200 ? response : null;
}
},
{
cachedResponseWillBeUsed: async ({cachedResponse}) => {
return cachedResponse;
}
}
]
})
);
В этом примере:
requestWillFetch),cacheKeyWillBeUsed),cacheWillUpdate),cachedResponseWillBeUsed.Эта структура позволяет четко контролировать каждый этап обработки запроса и кэша, избегая неожиданных конфликтов между плагинами.