Структура проекта для работы с sw-precache

Основная цель sw-precache — автоматическая генерация Service Worker для кэширования ресурсов веб-приложения, что позволяет обеспечивать оффлайн-доступ и повышать производительность за счет предварительного кэширования статических файлов. Для эффективного использования библиотеки важно правильно организовать структуру проекта.


1. Корневая директория проекта

В корне проекта обычно располагаются следующие элементы:

/project-root
  ├── package.json
  ├── gulpfile.js / webpack.config.js
  ├── src/
  ├── dist/
  └── sw.js (опционально)
  • package.json — содержит зависимости проекта, включая sw-precache.
  • gulpfile.js или webpack.config.js — конфигурационные файлы для сборки, в которых интегрируется генерация Service Worker.
  • src/ — исходные файлы проекта (HTML, CSS, JS, изображения).
  • dist/ — сборка проекта, готовая к деплою.
  • sw.js — файл Service Worker, может создаваться автоматически или частично настраиваться вручную.

2. Исходные файлы

В src/ рекомендуется придерживаться следующей структуры:

/src
  ├── index.html
  ├── scripts/
  │   └── main.js
  ├── styles/
  │   └── main.css
  └── images/
      ├── logo.png
      └── icons/
  • HTML — основной входной файл приложения.
  • JS и CSS — разделение логики и стилей упрощает генерацию кэшируемых ресурсов.
  • Изображения — все статические ресурсы, которые должны попасть в кэш.

3. Директория сборки

После сборки проект в dist/ должен иметь структуру, близкую к исходной, но с оптимизированными и минифицированными файлами:

/dist
  ├── index.html
  ├── scripts/
  │   └── main.min.js
  ├── styles/
  │   └── main.min.css
  ├── images/
  └── sw.js
  • Минификация файлов позволяет уменьшить размер кэша.
  • sw.js создается sw-precache и содержит манифест кэшируемых ресурсов.

4. Конфигурация sw-precache

Конфигурация может храниться отдельным файлом sw-precache-config.js:

module.exports = {
  staticFileGlobs: [
    'dist/**/*.html',
    'dist/scripts/**/*.js',
    'dist/styles/**/*.css',
    'dist/images/**/*.{png,jpg,gif,svg}'
  ],
  stripPrefix: 'dist/',
  runtimeCaching: [
    {
      urlPattern: /\/api\//,
      handler: 'networkFirst'
    }
  ]
};
  • staticFileGlobs — указывает, какие файлы должны быть закэшированы при установке Service Worker.
  • stripPrefix — удаляет часть пути для корректного отображения в кэше.
  • runtimeCaching — динамическое кэширование ресурсов при запросах к серверу, полезно для API.

5. Интеграция с Gulp

Пример Gulp-задачи для генерации Service Worker:

const gulp = require('gulp');
const swPrecache = require('sw-precache');

gulp.task('generate-service-worker', function(callback) {
  swPrecache.write('dist/sw.js', {
    staticFileGlobs: [
      'dist/**/*.html',
      'dist/scripts/**/*.js',
      'dist/styles/**/*.css',
      'dist/images/**/*.{png,jpg,gif,svg}'
    ],
    stripPrefix: 'dist/'
  }, callback);
});
  • Задача создаёт sw.js на основе собранных файлов.
  • Можно добавлять дополнительные опции, такие как runtimeCaching, для сложных приложений.

6. Интеграция с Webpack

Для Webpack можно использовать плагин sw-precache-webpack-plugin:

const SWPrecacheWebpackPlugin = require('sw-precache-webpack-plugin');

module.exports = {
  entry: './src/scripts/main.js',
  output: {
    path: __dirname + '/dist',
    filename: 'scripts/main.js'
  },
  plugins: [
    new SWPrecacheWebpackPlugin({
      cacheId: 'my-app',
      filename: 'sw.js',
      staticFileGlobs: ['dist/**/*.{js,html,css,png,jpg,gif,svg}'],
      stripPrefix: 'dist/'
    })
  ]
};
  • Позволяет автоматически генерировать sw.js во время сборки.
  • Плагин интегрируется с существующей сборкой Webpack без изменения структуры проекта.

7. Практические рекомендации

  • Разделение исходников и сборки — критично для корректного кэширования. Service Worker должен работать с финальной, оптимизированной версией.
  • Использование stripPrefix — упрощает пути и предотвращает ошибки при регистрации Service Worker.
  • Runtime caching — для динамических ресурсов API, изображений с CDN или шрифтов.
  • Версионирование Service Worker — обновление кэша должно происходить через изменение хэша или версии в конфигурации, чтобы пользователи всегда получали актуальные файлы.

Эта структура позволяет поддерживать проект в чистом, модульном виде и обеспечивает корректную работу sw-precache для кэширования как статических, так и динамических ресурсов.