msw-storybook-addon icon indicating copy to clipboard operation
msw-storybook-addon copied to clipboard

[BUG] Interference with HMR

Open Zombobot1 opened this issue 3 years ago • 6 comments

Versions: "msw": "0.27.2", "msw-storybook-addon": "1.1.0",

I often get an error which forces me to reload storybook page. image

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)

Zombobot1 avatar Jun 17 '21 15:06 Zombobot1

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: image

Zombobot1 avatar Jun 19 '21 19:06 Zombobot1

I have a similar issue when using fetch-mock - see https://github.com/storybookjs/storybook/issues/18702

shiraze avatar Jul 13 '22 12:07 shiraze

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.

Arttse avatar Apr 04 '23 15:04 Arttse

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 avatar Apr 21 '23 16:04 yannbf

@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.

kettanaito avatar Apr 27 '23 13:04 kettanaito