mswjs / msw

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

msw in browser doesn't work with Vite #695

Closed midanosi closed 3 years ago

midanosi commented 3 years ago

Describe the bug

see title - I can't get msw browser to work at all with Vite as a bundler. Was working before with same setup except with Parcel as bundler.

Environment

Please also provide your browser version

chrome macos 89.0.4389.114

To Reproduce

Steps to reproduce the behavior:

  1. Use Vite as bundler
  2. build using vite --debug
  3. see in build debug output vite:spa-fallback Not rewriting GET /mockServiceWorker.js because the path includes a dot (.) character. +4s
  4. see error in browser console: A bad HTTP response code (404) was received when fetching the script.
  5. don't see [MSW started] in browser console (whatever the usual message is to indicate msw has started successfully)

Guess

this issue (has similar error as in vite build log) https://github.com/vitejs/vite/issues/2245 might have something to do with it? I tried the 'vite-plugin-rewrite-all' package mentioned in that issue, and it didn't work for me.

kettanaito commented 3 years ago

Hey, @midanosi. Can you please prepare a minimal reproduction repository and push it to GitHub for us to look at? Then we could address this issue faster. Thanks.

msutkowski commented 3 years ago

@kettanaito Made a quick example of it working with vite: https://github.com/msutkowski/msw-ts-vitejs.

@midanosi The only thing here is that you'd want to strip the mockServiceWorker file in the production build. I'd have to look through the config on how to do that.

msutkowski commented 3 years ago

Follow up: here's the way I'd actually recommend doing it: https://github.com/msutkowski/msw-ts-vitejs/pull/1/files.

This leverages the special web worker feature of vite, and skips the production & public folder issue altogether.

kettanaito commented 3 years ago

Woah, that's blazing fast, Matt! Do you think we could add your repo to examples?

midanosi commented 3 years ago

I followed the strategy by msutkowski in my repo, and it's working just fine now, thanks for providing the example that helped.

Also just got an email from someone else leaving a comment in this thread i thought? But can't see it here.. anyway they said that likely the only reason it wasn't working for me was that I hadn't put my mockServiceWorker file in /public, which was the case. Sorry for being dumb, and thanks for the help!

midanosi commented 3 years ago

Closing, because my issue is resolved

kettanaito commented 3 years ago

@midanosi there is nothing to apologize for. We are excited to hear that you've resolved the issue!

equiman commented 2 years ago

I found an article about how to config msw with vitest and works for me.

https://markus.oberlehner.net/blog/using-mock-service-worker-with-vitest-and-fetch/

milahu commented 2 years ago

A bad HTTP response code (404) was received when fetching the script

i had to run

npx msw init .

to create mockServiceWorker.js next to index.html in a vite project

docs: https://mswjs.io/docs/getting-started/integrate/browser

McGern commented 1 year ago

@msutkowski Thanks for the repo, got my example working (just learning msw and vite at the moment). Wondering if this could also be included so the worker is also imported conditionally and can be kept in a separate file?

const { worker } = await import("../src/mocks/browser");

Seems to work, but I don't know all the ins and outs of msw and service workers. Doing this allows noobs like me to follow along the msw setup docs and keep the mocks out of the app, but allow it to work with vite.

So my "prepare" function looksa bit like this:-

const prepare = async () => { if (import.meta.env.DEV) { await import("../public/mockServiceWorker.js?worker"); const { worker } = await import("../src/mocks/browser"); return worker.start(); } return Promise.resolve(); };

NOTE: this follows the msw basic default install docs. I ended up putting the mockServiceWorker into the root folder (as suggested by @milahu ) so it didn't end up getting pushed to the public folder, but the module is still imported in the dist assets folder which I don't know if that is an issue.