Vite-PWA plugin не работает runtimeCaching

Рейтинг: 0Ответов: 1Опубликовано: 22.03.2023

Я решил переделать своё приложение со своего serviceWorker на отдельный плагин vite, тк это просто удобнее. Вот мой конфиг:

import {defineConfig} from 'vite';
import laravel from 'laravel-vite-plugin';
import react from '@vitejs/plugin-react';

import path from 'path';
import {VitePWA} from "vite-plugin-pwa";

const manifest = {
    "theme_color"     : "#2B2B2B",
    "background_color": "#2B2B2B",
    "display"         : "standalone",
    "scope"           : "/",
    "start_url"       : "/farm",
    "name"            : "ColorBit",
    "short_name"      : "Mining",
    "description"     : ".........",
    "icons"           : [
        //..........
        {
            "src"    : "icons/maskable_icon.png",
            "sizes"  : "682x682",
            "type"   : "image/png",
            "purpose": "maskable"
        }
    ]
};

const getCache = ({ name, pattern, strategy = "CacheFirst" }: any) => ({
    urlPattern: pattern,
    handler: strategy,
    options: {
        cacheName: name,
        expiration: {
            maxEntries: 500,
            maxAgeSeconds: 60 * 60 * 24 * 60 // 2 months
        },
        cacheableResponse: {
            statuses: [0, 200]
        }
    }
});

export default defineConfig({
    plugins: [
        laravel({
            input  : [ 'resources/js/app.tsx',],
            refresh: true,
        }),
        react({
            fastRefresh: false
        }),
        VitePWA({
            registerType: 'autoUpdate',
            outDir      : path.resolve(__dirname, 'public'),
            manifest    : manifest,
            manifestFilename: 'manifest.webmanifest',
            injectRegister  : false,
            workbox         : {
                globDirectory: path.resolve(__dirname, 'public'),
                globPatterns : [
                    '{build,images,sounds}/**/*.{js,css,html,ico,png,jpg,mp4,svg}'
                ],
                globIgnores  : [
                    // 'storage/**/*',
                    '**/telescope/**/*',
                ],
                // globFollow: false,
                swDest       : 'public/serviceWorker.js',
                runtimeCaching: [
                    getCache({
                        pattern: /^https:\/\/fonts\.googleapis\.com\/.*/i,
                        name: "google-fonts-cache",
                    }),
                    getCache({
                        pattern: /^https:\/\/fonts\.gstatic\.com\/.*/i,
                        name: "gstatic-fonts-cache"
                    }),
                    getCache({
                        pattern: /.*storage.*/,
                        name: "dynamic-images-cache",
                    }),

                ]
            }
        })
    ],
    resolve: {
        alias     : {
            '@'          : path.resolve(__dirname, 'resources/js'),
            '@hooks'     : path.resolve(__dirname, 'resources/js/hooks'),
            '@assets'    : path.resolve(__dirname, 'resources/js/assets/'),
            '@components': path.resolve(__dirname, 'resources/js/components')
        },
        extensions: ['.js', '.ts', '.tsx', '.jsx'],
    },
});

Он генерирует serviceWorker.js в папке public, которая на сервере laravel являет корневой, его я регистрирую самостоятельно в app.ts, привязываю подключение уведомлений и тд. Вот так выглядит папка public

Public

Конфиг генерирует при vite build мне нужный SW, добавляет файлы из build, icons, images и тд в precache - этот кэш я могу увидеть в dev tools -> application -> cache storage. Но проблема в том, что динамического runtime cache там не появляется (dynamic-images-cache для файлов из папки storage). введите сюда описание изображения

Как решить эту проблему? Вроде всё согласно гайдам в интернете и документации.

Ответы

▲ 1Принят

При регистрации serviceWorker.js в консоли выводилась ошибка

WorkboxError.js:28 Uncaught (in promise) non-precached-url: non-precached-url :: [{"url":"index.html"}] at x.createHandlerBoundToURL (http://localhost:5000/workbox-a59a8da5.js:1:12967) at Object.createHandlerBoundToURL (http://localhost:5000/workbox-a59a8da5.js:1:14597) at http://localhost:5000/sw.js:1:10085 at http://localhost:5000/sw.js:1:695 s @ WorkboxError.js:28.

Изучив сгенерированный workbox'ом serviceWorker.js я увидел, что он добавляет в кэш index.html файл, которого у меня нет, тк приложение на laravel.

Я нашел 2 варианта, как это исправить:

  • Самый банальный удалить из сгенерированного sw.js строчку, которая кэширует index.html.
  • Либо добавитьв конфиг workbox navigateFallback: null. Далее пример правильного конфига

VitePWA({
  registerType: 'autoUpdate',
  outDir: path.resolve(__dirname, 'public'),
  manifest: manifest,
  manifestFilename: 'manifest.webmanifest', // Change name for app manifest
  injectRegister: false, // I register SW in app.ts, disable auto registeration
  workbox: {
    globDirectory: path.resolve(__dirname, 'public'), // Directory for caching
    globPatterns: [
      '{build,images,sounds,icons}/**/*.{js,css,html,ico,png,jpg,mp4,svg}'
    ],
    globIgnores: [
      '**/telescope/**/*', // (work for dynamic and static cache!)
    ],
    navigateFallback: null, // Say that we don't need to cache index.html
    swDest: 'public/serviceWorker.js',
    runtimeCaching: [
      // Google fonts cache
      getCache({
        pattern: /^https:\/\/fonts\.googleapis\.com\/.*/i,
        name: "google-fonts-cache",
      }),
      // Google fonts api cache
      getCache({
        pattern: /^https:\/\/fonts\.gstatic\.com\/.*/i,
        name: "gstatic-fonts-cache"
      }),
      // Dynamic cache for assets in storage folder
      getCache({
        pattern: /.*storage.*/,
        name: "dynamic-images-cache",
      }),

    ]
  }
})