Chrome reloads infinitely when `serviceWorker.options.scope` is set
Prerequisites
- [X] I confirm my issue is not in the opened issues
- [X] I confirm the Frequently Asked Questions didn't contain the answer to my issue
Environment check
- [X] I'm using the latest
mswversion - [X] I'm using Node.js version 14 or higher
Browsers
Chromium (Chrome, Brave, etc.)
Reproduction repository
https://github.com/mizdra/reproduction-msw-scope-bug
Reproduction steps
-
npm i -
npm run dev - Open http://localhost:5173/base with Google Chrome
- I use
Google Chrome 112.0.5615.137(Official Build) (arm64)on masOS Monterey 12.6.
- I use
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.
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:
- https://github.com/mswjs/msw/blob/da92465b312b54a7a7e71168b1bdcb62daeef3b1/src/setupWorker/start/utils/getWorkerInstance.ts#L33
In addition to Chrome, this problem was reproduced in Firefox. However, it did not reproduce in Safari.
same problem for me any updated ?
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.
Can confirm the same is happening for me.
- MSW Worker file added to a static directory (non-root).
- Path set via
serviceWorker.urlin.start(). No handlers set up at this stage. - Activating the worker using
worker.start()will cause the site to reload indefinitely. - As above, looking at the Network Initiator tab identifies it as MSW causing the reload.
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.jsis at/some-path/mockServiceWorker.jsso 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-pathby checking current path - Cons is that you cannot stub request at
/some-pathpage.
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',
}
});
}
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:
- setup worker url (file path is apps/app1/public/mockServiceWorker.js)
apps/app1/src/App.tsx:
worker.start({
onUnhandledRequest: "bypass",
serviceWorker: {
url: "./mockServiceWorker.js",
},
})
- create base url similarly to @ptantanis comment, note the 2 slashes:
apps/app1/vite.config.ts:
export default defineConfig({
base: "/myBaseUrl/",
server: {
port: 1234
}
...
}
- access app at http://localhost:1234/myBaseUrl/
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.jsis at/some-path/mockServiceWorker.jsso 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-pathby checking current path- Cons is that you cannot stub request at
/some-pathpage.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.