Как использовать ServiceWorker без отдельного файла JS?


Мы создаем работников сферы услуг по

navigator.serviceWorker.register('sw.js', { scope: '/' });

Мы можем создать новый Workers без внешнего файла, подобного этому,

var worker = function() { console.log('worker called'); };
var blob = new Blob( [ '(' , worker.toString() , ')()' ], {
    type: 'application/javascript'
});
var bloburl = URL.createObjectURL( blob );
var w = new Worker(bloburl);

При подходе, использующем blob для создания ServiceWorkers, мы получим Security Error, поскольку bloburl будет blob:chrome-extension..., и происхождение не будет поддерживаться работниками сервиса.

Можно ли создать Service worker без внешнего файла и использовать область видимости как /?

2 4

2 ответа:

Я настоятельно рекомендую не пытаться обойти требование, чтобы код реализации Service worker жил в отдельном файле. Существует очень важная часть жизненного цикла Service worker, updates, которая основана на том, что ваш браузер может периодически извлекать ваш зарегистрированный ресурс JavaScript service worker и выполнять сравнение байт за байтом, чтобы увидеть, изменилось ли что-нибудь.

Если что-то изменилось в вашем служебном коде, то новый код будет считается работником службы installing, и старый код работника службы в конечном итоге будет считаться работником службы redundant, Как только все страницы, на которых зарегистрирован и выгружен/закрыт старый код.

Хотя поначалу вам будет немного сложно разобраться, понимание и использование различных состояний/событий жизненного цикла Service worker очень важны, если вы беспокоитесь об управлении кэшем. Если бы не эта логика обновления, как только вы зарегистрировали работника службы для данного scope однажды, он никогда не откажется от контроля, и вы застряли бы, если бы у вас была ошибка в коде/нужно было добавить новую функциональность.

Один из самых хитрых способов-использовать один и тот же файл javascript, понимать контекст и действовать как ServiceWorker, так и вызывающий его.

HTML

<script src="main.js"></script>

Главная.js

if(!this.document) {
    self.addEventListener('install', function(e) {
        console.log('service worker installation');
    });
} else {
    navigator.serviceWorker.register('main.js')
}

Чтобы предотвратить сохранение этого как большого файла main.js, мы могли бы использовать,

if(!this.document) {
    //service worker js
    importScripts('sw.js');
else {
    //loadscript document.js by injecting a script tag
}
Но это может вернуться к использованию отдельного файла sw.js для service worker, чтобы быть лучшим решением. Это было бы полезно, если бы вы хотели иметь единую точку входа в сценарии.