mswjs / msw

Industry standard API mocking for JavaScript.
https://mswjs.io
MIT License
15.98k stars 519 forks source link

Chrome reloads infinitely when `serviceWorker.options.scope` is set #1627

Open mizdra opened 1 year ago

mizdra commented 1 year ago

Prerequisites

Environment check

Browsers

Chromium (Chrome, Brave, etc.)

Reproduction repository

https://github.com/mizdra/reproduction-msw-scope-bug

Reproduction steps

  1. npm i
  2. npm run dev
  3. Open http://localhost:5173/base with Google Chrome
    • I use Google Chrome 112.0.5615.137(Official Build) (arm64) on masOS Monterey 12.6.

Current behavior

Reloading the page many times at short intervals will cause it to enter an infinite reload loop.

https://github.com/mswjs/msw/assets/9639995/dab75c08-f022-4591-8b08-41e072ac37c1

Expected behavior

No infinite loops.

mizdra commented 1 year ago

If you interrupt the reload at the right time, you can take a peek at the code that requested the reload from the initiator tab.

https://github.com/mswjs/msw/assets/9639995/0b030ba5-7067-4074-bf2c-76ee16365f57

According to this, the following code appears to be causing infinite reloads:

mizdra commented 1 year ago

In addition to Chrome, this problem was reproduced in Firefox. However, it did not reproduce in Safari.

MarwenIs commented 1 year ago

same problem for me any updated ?

mizdra commented 1 year ago

This problem does not yet seem to have been fixed.

FYI: You can temporarily work around this issue by installing ServiceWorker in the root path instead of using scope. This workaround only works for applications where it is not required to install under a subpath.

shapedigital commented 1 year ago

Can confirm the same is happening for me.

ptantanis commented 1 year ago

This is my workaround which maybe useful for some cases.

For me, I got infinite reload when init mswjs outside of service worker scope.

let's say

workaround

krzysztofradomski commented 3 months ago

This problem still exits in msw: 2.3.1 and I encountered it while setting up our nx monorepo of React/Vite apps.

Here is the workaround:

apps/app1/src/App.tsx:

  worker.start({
    onUnhandledRequest: "bypass",
    serviceWorker: {
      url: "./mockServiceWorker.js",
    },
  })

apps/app1/vite.config.ts:

export default defineConfig({
  base: "/myBaseUrl/",
  server: {
    port: 1234
  }
  ...
}
huygn commented 3 months ago

This is my workaround which maybe useful for some cases.

For me, I got infinite reload when init mswjs outside of service worker scope.

let's say

  • mockServiceWorker.js is at /some-path/mockServiceWorker.js so service worker scope is /some-path/
  • Service worker url is configured to /some-path/mockServiceWorker.js
  • When try to init mswjs at /some-path, then cause infinite reload. (init at /some-path/ is working fine because it's in service worker scope)

workaround

  • Not init mswjs at path /some-path by checking current path
  • Cons is that you cannot stub request at /some-path page.
if (window.location.pathname.startsWith('/some-path/')) { // only init mswjs when path is in service worker scope
  const worker = setupWorker(...handlers);

  void worker.start({
    serviceWorker: {
      url: '/some-path/mockServiceWorker.js',
    }
  });
}

Thanks for the workaround! Alternatively, if you own your Web hosting server it is possible to "upgrade" SW scope by using Service-Worker-Allowed .ie including Service-Worker-Allowed: / in the worker file's response.