msw-storybook-addon
msw-storybook-addon copied to clipboard
[BUG] Interference with HMR
Versions: "msw": "0.27.2", "msw-storybook-addon": "1.1.0",
I often get an error which forces me to reload storybook page.
I suppose that MSW intercepts one of HMR requests and fails.
At the same time I see this error in console: [MSW] Failed to mock a "GET" request to "http://localhost:6006/4cb31fa2eee22cf5b32f.hot-update.json": TypeError: Cannot read property 'id' of undefined at handleRequest (http://localhost:6006/mockServiceWorker.js:117:34)
I had to turn off this addon, because my storybook got completely broken. It cannot load anything and my console is full of errors like this:
I have a similar issue when using fetch-mock - see https://github.com/storybookjs/storybook/issues/18702
Faced the same problem when using this. I've found solution from this discussion https://github.com/mswjs/msw/discussions/1424 by creating custom worker with filtering by URL.
For example, create custom worker:
// public/apiMockServiceWorker.js
self.addEventListener('fetch', (event) => {
const url = new URL(event.request.url);
if (!url.pathname.startsWith('/api/')) {
// Do not propagate this event to other listeners (from MSW)
event.stopImmediatePropagation();
}
});
importScripts('./mockServiceWorker.js');
then initialize with custom worker:
// .storybook/preview.js
import { initialize, mswDecorator } from 'msw-storybook-addon';
// Initialize MSW with custom worker
initialize({
serviceWorker: { url: '/apiMockServiceWorker.js' },
});
now MSW intercepts only URLs with pathname starts with /api/
, like http://localhost/api/items
other will be go through over the network, so HMR now works.
Hey @Arttse thank you so much for providing that solution. I added a troubleshooting section in the docs do refer to your comment as a workaround.
@kettanaito I guess there's no better solution than that? In Storybook there are definitely requests which we could potentially filter out by default e.g. hot-update.json but also any request coming from vendors in node_modules, etc to detract the noise and improve performance. However if that's a MSW limitation then there's nothing we can do, right?
I also saw this very interesting comment about using request.passthrough on specific requests. Would that help in this situation?
@yannbf, using req.passthrough()
in a pre-defined set of handlers shipped by the add-on is the way to go! So, if we're expecting certain HMR requests from Storybook, we should create handlers for them and instruct MSW to pass through them.
rest.get('/hot-update/*', (req) => req.passthrough())
We can utilize RegExp and other ways to build up these request paths.
Once we have this set of handlers, we need to initialize MSW with them, allowing the end-user to add their own handlers on top.
I'm open to discussion on this if you think this API is unsuitable. But, generally, if you want to affect the network, you do that only via request handlers.