Set up Mock Service Worker in the browser, (1) generate a worker script via the npx msw init
command; (2) create mocks/borwser.ts
and use setupWorker()
to create a worker instance; (3) defer your application's rendering in entry.client.tsx
by introducing an enableMocking()
function that calls await worker.start()
.
Transcript
[00:00] To intercept WebSocket connections on the client, we have to enable MSW in the browser. To do that, open your terminal and type npx msw init. This command will copy the service worker script that MSW needs to run in the browser into whichever public directory you provide. Since we have a remakes app, our public directory is located in the root level public folder, so I will provide it with public. If you are prompted to save the public directory, you can choose yes, and this will store it in package.json so the worker script stays in sync with whichever version of MSW you are using.
[00:40] You can verify this by going to the public directory and locating mockserviceworker.js file there. Now let's head to the app directory and create a new folder called mocks. In this folder create a new file called browser.ts. In the browser.ts module import setupWorker from msw slash browser. Create a new variable called worker and assign it the result of the setupWorker call.
[01:11] This will configure this worker object so you're able to control MSW in the browser to start and stop the interception or affect it by appending new request handlers. Lastly, export this worker object so you're able to reference it elsewhere. The setupWorker function accepts request handlers as an argument. Request handlers are functions responsible for intercepting requests and handling their responses. You can provide them inline over here, but instead let's go to the mocks directory and create a new file called handlers.ts.
[01:44] In here, export a new variable called handlers, which will equal an empty array for now. Head back to the browser.ts and let's import these handlers. And then spread them as the argument to the setup worker call. The browser integration is ready but now we need to start it. Go to the entry.client.ts module and create a new function called enableMocking.
[02:13] Mark this function as asynchronous and then await a dynamic import to mocks slash browser. In here, access the worker object that we created earlier and call awaitWorker.start. This will start the service worker in the browser. Since we don't want to have MSW running in production, let's wrap this logic in a condition, saying that only if process environment node environment is development, we're going to enable MSW. Starting a service worker in the browser is an asynchronous action, so to prevent the race condition between the worker start and our application rendering, let's wrap this rendering in the enableMocking function.
[02:59] Let's call this function and provide the then handler and move the rendering logic inside that handler. This way the application will only start when MSW is enabled and ready to intercept requests. To verify our browser integration for MSW, Let's run our Remix app, head to the browser, and open the DevTools. In the console, we should see the mocking-enabled message printed by MSW.