sw-precache — это инструмент для автоматической
генерации Service Worker, который кэширует ресурсы веб-приложения,
обеспечивая быстрый офлайн-доступ и улучшая производительность. Одной из
ключевых задач при работе с современными сборщиками, такими как Webpack
или Parcel, является правильное управление хэшированными именами
файлов, которые генерируются для контроля версий ресурсов.
Хэширование файлов позволяет браузеру автоматически обновлять кэш при
изменении контента. Проблема заключается в том, что имена файлов не
статичны, поэтому нужно корректно передавать их в
sw-precache.
sw-precache для хэшированных ресурсовОсновной способ интеграции — использовать параметр
staticFileGlobs, который принимает массив путей к
статическим ресурсам. При работе с хэшированными файлами этот подход не
всегда удобен, так как хэш в имени меняется при каждой сборке. Вместо
этого используется динамическая генерация списка ресурсов через
file manifest.
Пример конфигурации с использованием шаблона:
const path = require('path');
const swPrecache = require('sw-precache');
const fs = require('fs');
const buildPath = path.join(__dirname, 'dist');
function getManifestFiles() {
const manifest = [];
const files = fs.readdirSync(buildPath);
files.forEach(file => {
if (/\.(js|css|html)$/.test(file)) {
manifest.push(`/dist/${file}`);
}
});
return manifest;
}
swPrecache.write(path.join(buildPath, 'service-worker.js'), {
staticFileGlobs: getManifestFiles(),
stripPrefix: path.join(__dirname, 'dist'),
});
В этом примере:
fs.readdirSync(buildPath) считывает все файлы из папки
сборки./\.(js|css|html)$/ фильтрует
только нужные ресурсы.stripPrefix удаляет лишний префикс пути, чтобы
кэшируемые URL были корректными относительно корня сайта.sw-precache с WebpackПри интеграции с Webpack хэшированные файлы создаются с помощью
[hash] или [contenthash] в имени. Для работы с
ними нужно генерировать список файлов автоматически после сборки.
Пример использования в webpack.config.js:
const path = require('path');
const SWPrecacheWebpackPlugin = require('sw-precache-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash].js'
},
plugins: [
new SWPrecacheWebpackPlugin({
cacheId: 'my-app',
filename: 'service-worker.js',
staticFileGlobs: ['dist/**/*.{js,css,html}'],
stripPrefix: 'dist/',
mergeStaticsConfig: true,
dontCacheBustUrlsMatching: /\.[0-9a-f]{8}\./
})
]
};
Ключевые моменты конфигурации:
staticFileGlobs указывает паттерн для
поиска файлов с хэшированными именами.dontCacheBustUrlsMatching
предотвращает добавление лишнего кэш-баста к уже хэшированным именам,
так как они уникальны по содержимому.stripPrefix корректирует пути для
Service Worker.Для файлов, чьи имена неизвестны заранее (например, генерируемые
изображения или данные API), можно использовать
runtimeCaching:
runtimeCaching: [
{
urlPattern: /\/api\//,
handler: 'networkFirst',
options: {
cache: {
name: 'api-cache',
maxEntries: 50,
maxAgeSeconds: 300
}
}
}
]
Это позволяет Service Worker кэшировать ответы динамически, не завися от хэшированных имен, и при этом поддерживать актуальность данных.
На больших проектах удобно создавать JSON-манифест с файлами сборки,
а затем передавать его в sw-precache:
const buildManifest = require('./dist/asset-manifest.json');
swPrecache.write(path.join(__dirname, 'dist', 'service-worker.js'), {
staticFileGlobs: Object.values(buildManifest),
stripPrefix: path.join(__dirname, 'dist'),
});
Здесь:
asset-manifest.json формируется сборщиком и содержит
все файлы с хэшами.service-worker.js всегда должен загружаться
напрямую.Эта схема работы позволяет полностью интегрировать
sw-precache с любым современным сборщиком, сохраняя
преимущества хэшированных файлов и минимизируя проблемы с устаревшим
кэшем.