Skip to content

vue-cli-pwa serves some weird service-worker.js. Service Workers are not just for caching. #4801

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

Open
MichaelJCole opened this issue Nov 5, 2019 · 8 comments

Comments

@MichaelJCole
Copy link

MichaelJCole commented Nov 5, 2019

Version

4.0.5

Reproduction link

https://www.npmjs.com/package/@vue/cli-plugin-pwa

localhost:8080/service-worker.js is returning some weird code I didn't write.

Reading the docs, the plugin is doing this to prevent "caching problems".

Service Workers can do more than "caching", and running Service Workers in development is necessary to develop application features that depend on them.

Steps to reproduce

Read the docs here:

https://www.npmjs.com/package/@vue/cli-plugin-pwa

The docs indicate I should compile for production, then do development. This doesn't make sense.

Also, the plugin serves non-functional code that I didn't write into my application. There doesn't seem to be a way to override this feature, and run my code in development.

Here is the plugin code:
https://github.com/MichaelJCole/vue-cli/blob/dev/packages/%40vue/cli-plugin-pwa/index.js

How can I run my service worker in development?

What is expected?

To run my code.

What is actually happening?

Some weird code I didn't write is running.

@birender
Copy link

Hi
Vue command not recongized in command prompt after successfully install vue
OS : Window 10 Home Edition 64 Bit
Error on Command Prompt
is not recognized as an internal or external command,
operable program or batch file.
internal/modules/cjs/loader.js:797
throw err;
^
Error: Cannot find module 'C:\Users\Birender \node_modules@vue\cli\bin\vue.js'
�[90m at Function.Module._resolveFilename (internal/modules/cjs/loader.js:794:15)�[39m
�[90m at Function.Module._load (internal/modules/cjs/loader.js:687:27)�[39m
�[90m at Function.Module.runMain (internal/modules/cjs/loader.js:1025:10)�[39m
�[90m at internal/main/run_main_module.js:17:11�[39m {
code: �[32m'MODULE_NOT_FOUND'�[39m,
requireStack: []
}
Thanks

@kubamarkiewicz
Copy link

+1 I have the same question: How can I run my service worker in development?

@MichaelJCole
Copy link
Author

MichaelJCole commented Nov 19, 2019

@kubamarkiewicz you can't with this "vue-cli-pwa" plugin. While there isn't a HMR "hot-reload" solution, this bug is about how this vue-cli-pwa plugin stops any solution.

It's not possible to develop a SW using the vue-cli's "vue serve".

AND, "vue serve" breaks for development once your Vue app starts using any custom SW features.

SO, once your app starts using your SW's features, you can't develop your app with "vue serve".

Instead of "vue serve", you have to iterate using "vue build" to create production build, then serve it yourself. We implemented VUE_APP_NO_MINIMIZE in our build stuff to help debugging. http-server is an npm package.

VUE_APP_NO_MINIMIZE=yesplease vue-cli-service build && cd dist && http-server -p 8080 --ssl --cert ../certs/private.crt --key ../certs/private.key -P https://api.to.proxy.here.com/"

My current client is paying me to iterate by building and deploying to a server because the app won't authenticate users from localhost (CORS). This is a 10 min iteration loop.

Developing the SW features, I was able to develop the service worker functionality on localhost with the app crashing by building and serving manually (2 min iteration loop).

Note that the Service Worker is an independent background process (like a hidden tab), so loading the "crashing" URL in the browser is just a way to attach the console to the service worker.

Once attached to the console, you can interact with the SW using fetch():

// One-liner to test custom feature enabled by header.
fetch("/robots.txt",{headers:{"Magic-Header":"magic-has-details"}}).then(res=>{console.log("RESPONSE:",res.status,res.statusText,res.headers.get("Magic-Header-Id")}).catch(error=>{console.log("ERROR.",error)})

// The Service worker's console.logs are output to the that tab's console.

// One liner to pass a message.  Set window.wb where you register the service worker.

wb.messageSW({type:"MAGIC_STUFF"}).then(stuff=>{console.log(stuff)}).catch(error=>{console.error(error)})

Other tips:

  • Firefox will bypass Chrome's problem with self-signed certs. Chrome on Linux has buggy broken features around this.
  • In Firefox, about:serviceworkers let's you unregister a SW which can speed up development.

@GeorgeGkinis
Copy link

GeorgeGkinis commented May 29, 2020

I just started developing a PWA with vue.
Quite disappointed by the missing hot-reload for development.

I commented out :

 // if (process.env.NODE_ENV === 'production') {
...
...
//}

and hot reload works again.

Tested by changing the text in :

ready () {
    console.log(
      'App is being served from cache by a service worker.\n' +
      'For more details, visit https://goo.gl/AFskqB \n' +
      'Now it is getting hot-reloaded again'
    )
  }

Not sure though what the implications will be, the console shows the added "Now it is getting hot-reloaded again'" text though implying that the service worker is updated.

Can anyone advise for any pitfalls this method may bring?

By the way I really love vue :)

Cheers!

@tempire
Copy link

tempire commented Jul 16, 2020

@MichaelJCole

AND, "vue serve" breaks for development once your Vue app starts using any custom SW features.
SO, once your app starts using your SW's features, you can't develop your app with "vue serve".

Why does it break? I keep seeing posts about how this shouldn't be done, but not the reasoning behind it.

@6a616e
Copy link

6a616e commented Nov 4, 2020

@MichaelJCole

AND, "vue serve" breaks for development once your Vue app starts using any custom SW features.
SO, once your app starts using your SW's features, you can't develop your app with "vue serve".

Why does it break? I keep seeing posts about how this shouldn't be done, but not the reasoning behind it.

I believe that there are some issues you can run into, because service worker caching can mess up hot reloading.
But I think it needs to be possible to activate service workers in development mode, if the developer explicitly enables it.

I have modified my @vue/cli-plugin-pwa/index.js (I disabled the NODE_ENV === 'production' condition and deactivated the createNoopServiceWorkerMiddleware) and it runs just fine. Sometimes a CTRL + R reload is necessary, but it works good enough for me to implement the feature.
I'd love to see a parameter for that in the vue.config.js for that, that would be still a hacky solution though.

The clean solution for this problem is to enable/disable only caching, depending on development/production mode.
A service worker has many other features (for example push notifications) that should not cause any problems when running in development mode.
The NODE_ENV should only determine if the precaching manifest is injected or not, not any other service worker code.

Maybe I am missing something here though. I have not tested my index.js hack enough to be sure it really works as expected. It's a bummer the pwa plugin does not really support service worker development. Would be great to see that in the future.

@elmatou
Copy link

elmatou commented Dec 2, 2020

Hi,
As others, I need to rebuild my whole app we I need to develop/debug my service worker, (which is not only caching by the way). I understand why HMR, will go haywire if caching is concurrently enabled.

One way would be to allow a build sequence only for the service-worker.js, and for the registerServiceWorker.js code.

This mode would not be default, and the operator would be responsible for disabling cache.

@elmatou elmatou mentioned this issue Dec 2, 2020
18 tasks
@FossPrime
Copy link
Contributor

FossPrime commented Apr 13, 2021

I went through the trouble of using build --watch to develop with my service worker. That's too slow for modern standards, roughly 40 seconds to see my changes. It's fast enough to debug production issues faster than actually pushing to a staging environment.

Everyone is saying a service worker will make HMR explode... but it sounds to me like it should be fairly easy to fix that by just adding a path exclusion to your service worker... will come back to this if I need faster service-worker development and fix it.

The fastest way to get it working is probably disable HMR, include the worker code via a custom webpack config and have the worker go into an amnesia mode during development.

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

No branches or pull requests

8 participants