Подстановочные знаки в ServiceWorker / Cache API

Я использую ServiceWorker и в режиме разработки работает отлично, моя проблема в том, что в производственном режиме мое имя пакета генерируется с использованием хеша, например 1234das3123ad5.bundle.jsпоэтому сервисный работник не кеширует его. Мой код SW выглядит так:

self.addEventListener('install', function(event) {
  // pre cache a load of stuff:
  event.waitUntil(
    caches.open('mycache').then(function(cache) {
      return cache.addAll([
        '/dist/bundle.js',
        '/dist/app.css',
        '/dist/index.html',
        'https://cdnjs.cloudflare.com/ajax/libs/antd/2.7.2/antd.css'
      ]);
    })
  )
});

В документации по Cache API я не вижу ни одного примера того, как мне этого добиться.

Очевидно, я мог кэшировать все под dist папка, имеющая что-то вроде:

self.addEventListener('install', function(event) {
  // pre cache a load of stuff:
  event.waitUntil(
    caches.open('mycache').then(function(cache) {
      return cache.addAll([
        '/dist/',
      ]);
    })
  )
});

Но я не нахожу это элегантным, хорошим в долгосрочной перспективе решением. Это способ иметь джокеры в кэше? Что-то вроде '/dist/*.bundle.js'?

3 ответа

Решение

В Интернете нет концепции папок, в частности, у браузера нет возможности узнать все действительные URL-адреса, начиная с префикса.

Остальная часть вашего сайта должна как-то обрабатывать изменения URL для пересмотра ресурсов, так почему бы не использовать то же решение в вашем сервисном работнике?

Это то, что я сделал для своего блога - статический файловый менеджер Django добавляет правильные URL-адреса https://jakearchibald.com/sw.js

Вот простой Node-скрипт, который создаст для вас массив имен файлов, при условии, что вы хотите получить список всех файлов в вашем веб / публичном каталоге. ПРИМЕЧАНИЕ: вы хотите запустить это из терминала на вашем public каталог.

var fs = require('fs');
var path = require('path');
var util = require('util');
var walk = function(dir, done) {
    var results = [];
    fs.readdir(dir, function(err, list) {
        if (err) return done(err);
        var i = 0;
        (function next() {
            var file = list[i++];
            if (!file) return done(null, results);
            //file = dir + '/' + file;
            file = path.resolve(dir, file);
            fs.stat(file, function(err, stat) {
                if (stat && stat.isDirectory()) {
                    walk(file, function(err, res) {
                        results = results.concat(res);
                        next();
                    });
                }
                else {
                    file = file.replace('/home/ubuntu/workspace/public', '');
                    results.push(file);
                    next();
                }
            });
        })();
    });
};
var mydir = path.resolve(__dirname);
walk(mydir, function(err, results) {
    if (err) throw err;
    console.log(util.inspect(results, { maxArrayLength: null }));
});

У меня возникли некоторые проблемы с этим, с vue3 pwa. Так что это не верный ответ, а, надеюсь, ценный ответ.

С vue3 созданный файл сервисного работника включает:

      importScripts(
  "/precache-manifest.\<something-something\>.js"
);

и сгенерированный файл precache-manifest.js содержит список всех элементов js, css и шрифтов, созданных при выполнении "сборки vue-cli-serve", например, что-то вроде:

      self.__precacheManifest = (self.__precacheManifest || []).concat([
  {
    "revision": "f715169493da60af08a445c4f7990905",
    "url": "/.htaccess"
  },
  {
    "revision": "87260e830ed912c46685c0a5432addf2",
    "url": "/.well-known/web-app-origin-association"
  },
<snip>

Затем сценарий рабочей области берет этот список и кэширует упомянутые файлы.

Другие вопросы по тегам