Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Registering the service-worker in dev mode. #2396

Closed
antsmartian opened this issue May 28, 2017 · 12 comments
Closed

Registering the service-worker in dev mode. #2396

antsmartian opened this issue May 28, 2017 · 12 comments

Comments

@antsmartian
Copy link

antsmartian commented May 28, 2017

I just created the react-app by following the command:

create-react-app test

Now I want to play with service worker concepts in Dev mode. So I decided to write a simple service worker registration code over here:

export default function registerServiceWorker()
{
	 if('serviceWorker' in navigator) {
		navigator.serviceWorker.register(`${process.env.PUBLIC_URL}/service-worker.js`).then(function(register){
			console.log("worked", register);
		}).catch(function(err){
			console.log("error!")
		});
	}
}

And I registered by calling the function registerServiceWorker. Looks like the registration function works smoothly (as I could able to see the worked on the console log). However, I cannot see my real service-worker.js is called!

service-worker.js file looks like:

var cacheName = ‘helloWorld’;
self.addEventListener('install', event => { event.waitUntil(
	caches.open(cacheName).then(cache => cache.addAll([
		'/js/script.js',
		'/images/hello.png' ]))
	); 
});

But the caching is not working as I had given above in the code. Debugging shows that the service-worker.js file which is loaded by the browser something else. Not sure what mistake I'm making here. May be this is an issue?

Note I'm running the application using npm start

Thanks for the help.

@antsmartian
Copy link
Author

antsmartian commented May 28, 2017

Looks like this is the reason : https://github.com/facebookincubator/create-react-app/pull/2276/files

What ever service worker I write, its getting replaced by the following code:

// This service worker file is effectively a 'no-op' that will reset any
// previous service worker registered for the same host:port combination.
// In the production build, this file is replaced with an actual service worker
// file that will precache your site's local assets.
// See https://github.com/facebookincubator/create-react-app/issues/2272#issuecomment-302832432
self.addEventListener('install', () => self.skipWaiting());
self.addEventListener('activate', () => {
  self.clients.matchAll({ type: 'window' }).then(windowClients => {
    for (let windowClient of windowClients) {
      // Force open pages to refresh, so that they have a chance to load the
      // fresh navigation response from the local dev server.
      windowClient.navigate(windowClient.url);
    }
  });
});

Let me know how could I overcome this?

Edit:

Ok if I change my service-worker.js to say service-worker2.js then everything works! But wondering why the default option is replacing my worker file. Please let me know

@gaearon
Copy link
Contributor

gaearon commented May 28, 2017

It is intentional. Using a service worker in development can lead to extremely confusing debugging situations. Perhaps there's a better way we could handle it.

@antsmartian
Copy link
Author

Ok thanks for the update. If one can't play with service worker in Dev mode how one shall create them? I know in production mode out of box we get the service worker to cache static assets etc. But still I need to play in Dev mode as well. Let me know if there are any better way to handle them.

@gaearon
Copy link
Contributor

gaearon commented May 29, 2017

There is no support for custom service workers at the moment.

@antsmartian
Copy link
Author

@gaearon Thanks Dan. So currently I'm creating a service worker with a different name, so that I can escape from being replaced. Kindly let me know if that will be good enough to say just create POC with React & Service worker or may be to opt for normal starter kits. Thanks for you'r help.

@jeffposnick
Copy link
Contributor

Registering a service worker with a name other than service-worker.js (you can use sw.js, or service-worker2.js like you're using) will avoid the behavior you describe, and allow you to test out your custom service worker when NODE_ENV isn't production. That sounds perfectly viable.

@antsmartian
Copy link
Author

antsmartian commented Jun 7, 2017

@jeffposnick Thanks!
@gaearon : If its an expected behavior, can I close it.

@gaearon gaearon closed this as completed Jun 26, 2017
@vaibhavi3t
Copy link

I also want to use the service worker in dev mode to test it. I'm not able to run it. As @antoaravinth did, I changed the service-worker file name but it is not registering it. Please help me out. How can I test it in dev mode?

@Altiano
Copy link

Altiano commented Dec 22, 2017

I think this should be on the docs
How about use environment variable?

@redixhumayun
Copy link

I've tried the same approach as @antoaravinth but I keep getting the error Error while registering DOMException: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/html')

How do I create and use a service worker in a dev environment?

@nick-gaudreau
Copy link

nick-gaudreau commented Apr 29, 2018

Thanks @antoaravinth for bringing this up. Myself I just wanted to use SW first as a POC then possibly something to include in a presentation.

@redixhumayun if you're still looking on how to do it in dev without changing the sw prod setup.

Create a simple sw register function in /src:

export default function LocalServiceWorkerRegister() {
    const swPath = `${process.env.PUBLIC_URL}/sw.js`;
    if ('serviceWorker' in navigator && process.env.NODE_ENV !== 'production') {
      window.addEventListener('load', function() {
        navigator.serviceWorker.register(swPath).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);
        });
      });
    }
}

Then in index.tsx import and call:

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import App from './App';
import './index.css';
import LocalServiceWorkerRegister from './sw-register';
//import registerServiceWorker from './registerServiceWorker';

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

LocalServiceWorkerRegister();
//registerServiceWorker();

Then call your dev service worker file: sw.js (something different than prod) and put it in your /public folder.

npm start

@Quadriphobs1
Copy link

But also what if I want to also do some custom manipulation of service worker in production and development. Say I want to fully make use of the service worker . Is there any support for this

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

8 participants