Для интеграции Workbox в процесс сборки с Gulp используется пакет
workbox-build. Он позволяет автоматически генерировать
Service Worker и управлять кэшированием ресурсов приложения. Установка
производится через npm:
npm install workbox-build --save-dev
После установки создаётся gulp-задача, которая отвечает за генерацию
Service Worker. Основные функции workbox-build —
generateSW и injectManifest.
generateSW создаёт полностью готовый Service Worker с
преднастроенными стратегиями кэширования, а injectManifest
позволяет использовать собственный шаблон Service Worker, в который
Workbox подставит манифест ресурсов.
const { src, dest, series } = require('gulp');
const workboxBuild = require('workbox-build');
function generateServiceWorker() {
return workboxBuild.generateSW({
globDirectory: 'dist',
globPatterns: [
'**/*.{html,js,css,png,jpg,svg}'
],
swDest: 'dist/sw.js',
runtimeCaching: [
{
urlPattern: /\.(?:png|jpg|jpeg|svg)$/,
handler: 'CacheFirst',
options: {
cacheName: 'images-cache',
expiration: {
maxEntries: 50,
maxAgeSeconds: 30 * 24 * 60 * 60,
},
},
},
{
urlPattern: new RegExp('https://api.example.com/'),
handler: 'NetworkFirst',
options: {
cacheName: 'api-cache',
networkTimeoutSeconds: 10,
expiration: {
maxEntries: 30,
maxAgeSeconds: 5 * 60,
},
},
},
],
});
}
exports.default = series(generateServiceWorker);
injectManifest для кастомного Service WorkerМетод injectManifest позволяет интегрировать Workbox в
существующий Service Worker. В этом случае в шаблоне SW можно
реализовать пользовательскую логику кэширования и обработку событий
install и activate.
function injectManifestSW() {
return workboxBuild.injectManifest({
swSrc: 'src/sw-template.js',
swDest: 'dist/sw.js',
globDirectory: 'dist',
globPatterns: [
'**/*.{html,js,css,png,jpg,svg}',
],
});
}
exports.buildSW = series(injectManifestSW);
В шаблоне Service Worker (src/sw-template.js) необходимо
импортировать Workbox через importScripts и настроить
стратегии кэширования для различных ресурсов:
importScripts('https://storage.googleapis.com/workbox-cdn/releases/6.6.0/workbox-sw.js');
workbox.precaching.precacheAndRoute(self.__WB_MANIFEST);
workbox.routing.registerRoute(
({request}) => request.destination === 'image',
new workbox.strategies.CacheFirst({
cacheName: 'images-cache',
plugins: [
new workbox.expiration.ExpirationPlugin({
maxEntries: 50,
maxAgeSeconds: 30 * 24 * 60 * 60,
}),
],
})
);
Gulp позволяет интегрировать Workbox в общий процесс сборки проекта. Например, можно комбинировать задачи минификации CSS/JS и генерации Service Worker:
const gulp = require('gulp');
const cleanCSS = require('gulp-clean-css');
const terser = require('gulp-terser');
function minifyCSS() {
return gulp.src('src/css/*.css')
.pipe(cleanCSS())
.pipe(gulp.dest('dist/css'));
}
function minifyJS() {
return gulp.src('src/js/*.js')
.pipe(terser())
.pipe(gulp.dest('dist/js'));
}
exports.build = gulp.series(
gulp.parallel(minifyCSS, minifyJS),
generateServiceWorker
);
Такой подход гарантирует, что Service Worker будет сгенерирован уже
после того, как все статические файлы окажутся в директории
dist, что исключает проблемы с отсутствием ресурсов в
кэше.
Workbox поддерживает несколько стратегий кэширования:
Каждую стратегию можно настроить с помощью плагинов, например,
ExpirationPlugin для ограничения количества записей в кэше
или CacheableResponsePlugin для фильтрации ответов по
HTTP-кодам.
После генерации Service Worker важно убедиться в корректности работы кэша. Для этого:
Workbox поддерживает обновление только изменённых файлов, что экономит время на пересборку:
workboxBuild.generateSW({
globDirectory: 'dist',
globPatterns: ['**/*.{js,css,html}'],
swDest: 'dist/sw.js',
dontCacheBustURLsMatching: /\.\w{8}\./
});
Флаг dontCacheBustURLsMatching предотвращает перезапись
ресурсов с хэшами в именах файлов, что ускоряет работу Service Worker
при частых изменениях контента.