如何在没有单独的 JS 文件的情况下使用 ServiceWorker?

How do I use ServiceWorker without a separate JS file?

我们通过

创建服务工作者
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 Workers 将不支持源。

是否可以在没有外部文件的情况下创建服务工作者并将范围用作 /

一种 hacky 方法是使用相同的 javascript 文件来理解上下文并充当 ServiceWorker 以及调用它的人。

HTML

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

main.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 生命周期中有一个非常重要的 updates,它依赖于您的浏览器能够定期获取您注册的 service worker JavaScript 资源并进行逐字节比较以查看是否有任何内容改变了。

如果您的 service worker 代码发生了变化,那么新代码将被视为 installing service worker,而旧的 service worker 代码最终将被视为 redundant service worker一旦所有注册了旧代码的页面和 unloaded/closed.

虽然一开始有点难以理解,但如果您担心缓存管理,那么理解和使用不同的 Service Worker 生命周期 states/events 很重要。如果不是这个更新逻辑,一旦你为给定的范围注册了一个 service worker 一次,它就永远不会放弃控制,如果你的 code/needed 中有一个错误来添加新的,你就会被卡住功能。