I'm trying to make use of the service worker in create-react-app but I keep getting…wont register sw. Current env: development

梦想的初衷 提交于 2020-07-23 11:38:13

问题


I'm using create-react-app but the service worker isnt working. Im using localhost

I'm trying to make this a PWA, i'm using the stock manifest file and service worker generated when you create-react-app, i've also rand npm run-script build and got the generated service-worker.js file. The problem is that I keep getting this in the console. wont register sw. Current env: development help?

window.addEventListener("load", () => {
   const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;

   if (isLocalhost) {
    // This is running on localhost. Let's check if a service worker 
       still exists or not.
        checkValidServiceWorker(swUrl, config);

    // Add some additional logging to localhost, pointing developers to 
      the
    // service worker/PWA documentation.
        navigator.serviceWorker.ready.then(() => {
          console.log(
            "This web app is being served cache-first by a service " +
              "worker. To learn more"
          );
        });
      } else {
        // Is not localhost. Just register service worker
        registerValidSW(swUrl, config);
      }
    });
  } else {
    console.log("wont register sw. Current env:", process.env.NODE_ENV);
  }
}

回答1:


Here are the steps:

Step 1: A new JavaScript file: svcWorker.js needs to be created in the public folder. Add the following code in it:

var CACHE_NAME = 'task-manager-pwa';
var urlsToCache = [
  '/',
  '/completed'
];

// Install service worker
self.addEventListener('install', event => {
  // Perform the install steps
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(function(cache) {
        console.log('Cache opened');
        return cache.addAll(urlsToCache);
      })
  );
});

// Cache and return the requests
self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request)
      .then(function(response) {
        // Return response as Cache is hit 
        if (response) {
          return response;
        }
        return fetch(event.request);
      }
    )
  );
});

// Update service worker
self.addEventListener('activate', event => {
  var cacheWhitelist = ['task-manager-pwa'];
  event.waitUntil(
    caches.keys().then(cacheNames => {
      return Promise.all(
        cacheNames.map(cacheName => {
          if (cacheWhitelist.indexOf(cacheName) === -1) {
            return caches.delete(cacheName);
          }
        })
      );
    })
  );
});

Step 2: Make changes to the index.html file to check if the client browser supports service workers and also the application renders styling and works fine without any trace of JavaScript loading. Code for this is added between the <style> </style> and <body> </body> tags. Here is the full code in index.html:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1"
    />
    <meta name="theme-color" content="#000000" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />
    <link rel="apple-touch-icon" href="logo512.png" />
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    <title>React PWA App</title>
    <style type="text/css">
      body {
        margin: 0;
        padding: 0;
        font-family: sans-serif;
      }
      .navbar {
        background-color: #4169e1;
      }
      .navbar h3 {
        display: inline-block;
        text-align: left;
        padding: 10px;
        color: black;
        text-decoration: none;
      }
      .navbar a {
        display: inline-block;
        padding: 10px;
        color: #fff;
        text-decoration: none;
      }
      .page-info {
        padding: 10px;
      }
      .Current {
        color: #2e8b57;
      }
      .Completed {
        color: #ff6347;
        text-decoration: line-through;
      }
    </style>
  </head>
  <body>
    <noscript>Enable JavaScript to run this app.</noscript>
    <div id="root">
      <div class="navbar">
        <h3>Task Manager</h3>
        <a href="/">Present Tasks</a>
        <a href="/completed">Finished Tasks</a>
      </div>
      <p class="page-info">
        App Loading...
      </p>
    </div>
    <script>
      if ('serviceWorker' in navigator) {
        window.addEventListener('load', function() {
          navigator.serviceWorker.register('svcWorker.js').then(function(registration) {
            console.log('Worker registration is successful', registration.scope);
          }, function(err) {
            console.log('Worker registration has failed', err);
          }).catch(function(err) {
            console.log(err);
          });
        });
      } else {
        console.log('Service Worker is not supported by your browser.');
      }
    </script>
  </body>
</html>

Step 3: In index.js, make sure that you use: serviceWorker.register() Here is code in index.js:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

ReactDOM.render(<App />, document.getElementById('root'));

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
serviceWorker.register();

I have written all these steps and other steps to create a Simple React PWA App in my blog post with working code in GitHub. Please refer to: http://softwaredevelopercentral.blogspot.com/2019/10/react-pwa-tutorial.html




回答2:


Main think you need to know: Create the servieWorker inside public folder in order to be treated as .js file and not text/html file.

Then register that service in your index.js

Step 1, create public/sw.js

self.addEventListener('message', async (event) => {
  console.log('Got message in the service worker', event);
});

Step 2, create src/sw-register.js

export default function LocalServiceWorkerRegister() {
  const swPath = `${process.env.PUBLIC_URL}/sw-build.js`;
  if ('serviceWorker' in navigator && process.env.NODE_ENV !== 'production') {
    window.addEventListener('load', function () {
      navigator.serviceWorker.register(swPath).then(registration => {
        console.log('Service worker registered');
      });
    });
  }
}

Step 3, in src/index.js, add these two lines

import LocalServiceWorkerRegister from './sw-register';
...
LocalServiceWorkerRegister();

You can change some things for your needs, but with those changes, you should be able to work with a custom service worker in a create-react-app application



来源:https://stackoverflow.com/questions/57838179/im-trying-to-make-use-of-the-service-worker-in-create-react-app-but-i-keep-gett

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!