ReactJS ServiceWorker 在多个缓存文件中存储相同的代码

问题描述

我正在尝试使用此文件系统布局将 serviceworker 添加到现有 React 应用程序: Filesystem

基本上一些初始化代码存储在 public 文件夹中,所有重要的代码都在 src 文件夹中。在 serviceWorker.js 文件中,我创建了一个文件名数组来缓存并在“安装”事件侦听器中调用该数组,如果我检查 DevTools,我可以看到文件名存在于缓存中:当我预览数据时但是,Chrome DevTools,我看到缓存文件中的代码全部来自 index.html。事实上,我可以在文件名数组中添加任何我想要的东西,我会在缓存存储中找到它,却发现它正在存储 index.html 代码。似乎无论我尝试将什么文件添加到缓存中,都只会加载 index.html。

ServiceWorker.js:

let CACHE_NAME = "MG-cache-v2";

const urlsToCache = [
'/','/index.html','/src/App.js','/monkey'
 ];

self.addEventListener('install',function (event) {
//perform install steps
event.waitUntil(
    caches.open(CACHE_NAME).then(function (cache) {
        console.log('Opened MG_Cache');
        return cache.addAll(urlsToCache);
    }).catch(function (error) {
        console.error("Error loading cache files: ",error);
    })
);
self.skipwaiting();
});

self.addEventListener('fetch',function (event) {
event.respondWith(caches.match(event.request).then(function (response) {
    if (response) {
        return response;
    }

    return fetch(event.request);
})
);
});

self.addEventListener('activate',(event) => {
event.waitUntil(async function () {
    const cacheNames = await caches.keys();
    await Promise.all(
        cacheNames.filter((cacheName) => {
            //Return true if you want to remove this cache,//but remember that caches are shared across the whole origin
            return;
        }).map(cacheName => caches.delete(cacheName))
    );
})
})

index.html 的一部分:

 <script>
  if ('serviceWorker' in navigator)
   {
      window.addEventListener('load',function () {
          navigator.serviceWorker.register('serviceWorker.js').then(function (registration) {
              // Registration was successful
              console.log("ServiceWorker registration successful with scope: ",registration.scope);
          },function (err) {
                  // registration Failed :
                    (console.log('ServiceWorker registration Failed: ',err));
      });
      });
  }
  </script>

Google Devtools 预览版: All files are the same

我在文件名数组中尝试了多种命名策略,但都以相同的结果结束。在这一点上,我完全不知所措。

编辑:虽然这不能解决我的问题,但我发现了另一个问题的 answer,可以提供一些指导。服务器似乎从未找到我请求的文件,因此返回 index.html。我尝试将 serviceWorker.js 文件放在 src 文件夹中并将 service worker 注册移动到 App.js 并得到一个错误

`DOMException: Failed to register a ServiceWorker for scope ('http://localhost:3000/src/') with script ('http://localhost:3000/src/serviceWorker.js'): The script has an unsupported MIME type ('text/html'). `

这表明服务器无法访问 src 文件夹,只能访问公共文件夹。知道为什么会这样吗?

解决方法

我忽略了一条重要信息,即我正在使用 Create-React-App。由于文件系统的强制布局,serviceWorker 必须放在 public 文件夹中:同时,默认情况下,serviceWorker 的范围是它们所在的文件夹。根据 [TF2.0] Change default types globally 答案,更改服务工作者的范围要高于它所在文件夹的级别需要添加到服务工作者的 HTTP 标头响应中(不完全确定这意味着什么),并且做这样的事情假设您有某种形式的本地服务器设置。唉,到目前为止,我一直在使用 npm start 来测试我的应用程序并推送到 nsmp 以使网站上线,因此我自己忽略了做任何形式的服务器实现(我知道,我不是很聪明)。

我的修补程序是使用 npx create-react-app my-app --template cra-template-pwa 命令创建一个新的临时应用程序,从该应用程序中复制与 Service Worker 相关的所有文件(serviceWorkerRegistration.js、service-worker.js、index.js,可能还有 setupTests.js ),并将它们粘贴到我的应用程序中。然后我可以简单地遵循 this 教程。现在我的网站可以离线使用。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...